2012-02-29 47 views
6

我正在我的应用程序中构建一个嵌套的评论回复系统。如何结合这些MySQL查询,然后正确访问数据

目前一切正常,但我发现自己必须使用多个MySQL查询才能检索所需的数据。更糟糕的是,对'回复'的查询在foreach循环中。这意味着尽管目前它的表现令人钦佩,但它远非最佳,并且会随着数据集的增长而出现问题。

因此,我希望在深入研究之前解决这个问题。

由于该应用程序的表格与该网站的wordpress博客共享相同,因此我正在使用wordpress简写查询。

生成的页中的电流的方法是如下:

甲注释查询表以及与一个专案编号所有结果检索到: -

$commentquery = "select projects_comments.*, users.user_url, users.display_name 
       from ".$wpdb->prefix."projects_comments projects_comments 
       left join ".$wpdb->prefix."users users on users.ID=projects_comments.userid 
       where projectid = '$projectid' 
       order by projects_comments.commentid desc 
       "; 

$comments = $wpdb->get_results($commentquery); 

我然后如下进行foreach循环: -

if($comments) { 
      foreach ($comments as $c) 
       { 


       $replyquery = "select project_replies.*, users.user_url, users.display_name 

       from ".$wpdb->prefix."project_replies project_replies 
       left join ".$wpdb->prefix."users users on users.ID=project_replies.uid 
       where project_replies.cid = '$c->commentid' 
       order by project_replies.id desc   
       limit 2   
       ";  

       $replies = $wpdb->get_results($replyquery); 

       asort($replies); 

       $countquery = "select count(*) 

        from ".$wpdb->prefix."project_replies project_replies 
        where project_replies.cid='".$c->commentid."' 
        "; 

       $replycount = $wpdb->get_var($countquery); 

    //generate html here 
    } 
} 

在此循环内部还有两个查询。第一个获得每个评论的回复,但将结果限制为2(我希望这样做是为了有一个“查看所有回复”按钮,然后如果用户要求他们查询数据库的其余部分),第二个查询计数回复的总数。

在HTML然后也使用上述回路内的第二嵌套的foreach(在那里说生成这里HTML代码)的环内每个回复产生如下: -

if ($replies){ 

    foreach ($replies as $r){ 

    // generate each reply 
    } 
} 

所有数据被从拉这些阵列以下列方式:

$c->userid, $c->body etc... For the comments 
$r->userid, $r->body etc... For the replies. 

我希望保持这种格式,如果可能的话。

正如在问题开始时所述,这一切都很好,但我知道,通过嵌套答复和计数查询,我执行的查询超过了必要的数量。 100条评论将产生100条回复查询和100条回复查询等。

感谢本网站上的一些有帮助的人,我曾考虑过使用联接来一次性获取所有原始数据以进行评论和回复。是这样的...

$commentquery2 = "SELECT c.commentid, c.userid, c.body as cbody, c.projectid, c.posttime, cu.user_url AS cu_url, cu.display_name AS cu_name, 
        r.*, ru.user_url AS ru_url, ru.display_name AS ru_name 
       FROM ".$wpdb->prefix."projects_comments AS c 
       LEFT JOIN ".$wpdb->prefix."users  AS cu ON cu.ID = c.userid 
       LEFT JOIN ".$wpdb->prefix."project_replies AS r ON r.cid = c.commentid 
       LEFT JOIN ".$wpdb->prefix."users  AS ru ON ru.ID = r.uid 
       WHERE c.projectid = $projectid 
       ORDER BY c.commentid DESC, r.id DESC"; 

虽然这确实工作(并且是足以让我以纪念这个问题作为回答)时,把它付诸实践我有一些困难。

首先,这将检索所有数据作为单独的行,这意味着如果我有5条评论,每条评论有3条回复,我实际上得到15条返回的行,而不是嵌套数据对象,并且回复嵌套在每条评论行中。

为了解决这个我已经尝试了一些阵列操作,如下所示:

$old_id=NULL; 
$comments=array(); 

foreach($getcomments as $c){ 

    if($c->commentid !== $old_id){ 

     $comments[$old_id] = $c; 
     $old_id = $c->commentid; 

    } 


    $comments[$old_id]['replies'][] = $c; 


} 

这样做给我一个嵌套的数据对象作为必需的。但是,它不包括回复计数查询,并且它不会按照预期将每个回复集合限制为2,它将检索所有回复。

最后用foreach循环中我当前的HTML生成代码:

foreach($comments){ 

    //generate comment html 

    foreach($replies) { 

     //generate replies html 

    } 

} 

我似乎无法得到它与嵌套数据对象的正常工作。访问正确的深度答复似乎让我感到困惑。所以总而言之,我希望能够移除循环查询,将它们组合成一个更大且更高效的查询,或者最糟糕的情况下将它们组合成一个数据查询和一个单独的计数查询,然后创建一个整齐的嵌套数据对象,与行评论和任何回复嵌套在标题'回复'下

然后,我需要能够通过这些在我的PHP代码中正确地迭代,以便生成所需的HTML。

我对这个问题的长度道歉,并意识到它很可能把很多人都回答过,但我一直在这条直线现在作战19小时,真正需要的帮助。

非常感谢任何人谁提供的任何建议。

+0

也许只是将示例数据和生成的表格添加到表格中,您应该已经更有用了。 – 2012-02-29 17:12:48

+0

很可能是Mosty,指出。如果我没有那么匆忙,因为我从10分钟开始就有2小时的车程,所以我会按照你的建议编辑问题。 – gordyr 2012-02-29 17:15:34

+0

这已经覆盖了几次,包括这篇文章:http://stackoverflow.com/questions/317322/optimized-sql-for-tree-structures – crafter 2012-02-29 18:08:00

回答

2

如果您想保留留言和回复在两个不同的表(见工匠的评论),你可以用一个简单的一招消除环路:收集来自第一查询注释ID和使用

WHERE( CID IN(1,2,3,4,...))

,而不是循环。如果您需要限制每条评论的回复,那么应该可以使用额外的WHERE-或HAVING子句。

BurninLeo

+0

感谢BurninLeo。虽然这让我开始了很长的路要走,但我想让问题稍微长一些,希望能够获得更多的答复/解决方案。我希望你明白。 – gordyr 2012-03-01 17:26:25

+0

我甚至不确定这是否真的是你需要的;)我也对其他意见感兴趣。只要我找到一些时间,我也会阅读链接在你的问题的评论链接的线程中的嵌套集的介绍... – BurninLeo 2012-03-02 08:04:50