mySQL查询中的条件限制可能吗?

时间:2009-11-30 21:30:56

标签: sql mysql conditional limit

我面临着关于在项目中处理线程评论的决定...... 我有一个简单的MySQL表,其中包含所有注释。有两种类型:父母和孩子。孩子代表对父母或另一个孩子的回复。

我的问题:

- 成绩(深度0)
- 回复儿童(深度1)
---回复前一个孩子(深度2)
- 成绩(深度0)

想象一下上面的结构和带有LIMIT 2的MySQL查询。它将剪切最后一个回复(深度2)。其实我想说的是:尝试限制为2,如果孩子离开,直到下一个父母。尝试了几个没有运气的问题......

我现在所拥有的是如下:
    选择     SQL_CALC_FOUND_ROWS         *     从         评论     哪里         comment_post_id ='{$ _REQUEST [“ID”]}'     订购         comment_id,comment_date     DESC LIMIT 10“

重要的表格字段是:
comment_id(index)| comment_parent_id(包含parent的comment_id或NULL)| comment_date

我会非常感谢任何想法!

Saludos, Booosh

4 个答案:

答案 0 :(得分:1)

MySQL没有任何解析树状结构的函数。在最简单的场景中(子节点具有父节点的ID),您需要以编程方式递归到树中以定位给定节点的所有子节点。 MaxLevel表示您要去的深度。它会随着每次递归调用而递减,以便在结束时最终得到0,这会停止递归。

e.g。 (伪代码)

findNodes(String parentId, int maxLevel)
{
  select * from posts where parent = parentId
  foreach (result...)
  {
    if (maxLevel > 0) 
    {
      findNodes(result.nodeId, maxLevel - 1)
    }
    doSomethingWIthAResult
  }
}

为了以更简洁的方式执行此操作,有许多技术,所有这些技术都涉及某种索引字段,其中包含当前帖子的路径。路径看起来像这样:TopNode:Child1:Child2:Child3 ...你可以在这里做一个像这样的选择 从帖子中选择*,其中路径如“TopNode%”和depth = 2。

答案 1 :(得分:1)

总是考虑一下你真正想问问数据库的问题,然后将其翻译成SQL - 在这种情况下,你想要“与他们的直接孩子一起列出所有顶级评论,如果有的话”

例如。 (简化的)

SELECT * FROM comments c1
LEFT JOIN comments c2 ON c2.parent_comment_id=c1.comment_id
WHERE c1.parent_comment_id IS NULL
ORDER BY c1.comment_date, c1.comment_id, c2.comment_date, c2.comment_id;

有了这个结果,你可以按正确的顺序写出来 - 如果c2.comment_id为null,它是没有孩子的顶级评论,如果重复c1.comment_id,那么它是同一评论的另一个孩子。

答案 2 :(得分:1)

我遇到了同样的问题,只是我只走了一个深度。

--Comment (depth: 0)
---Reply  (depth: 1)

我设法使用单个查询来选择所有这些记录,同时将顶级Comment记录限制为仅10个。

SELECT c.* FROM comments AS c WHERE c.OwnerId = 1 AND c.ParentId = 0 LIMIT 10
UNION
SELECT cc.* FROM comments AS cc
    INNER JOIN
    (
        SELECT CommentId FROM comments WHERE OwnerId = 1 AND ParentId = 0 LIMIT 10
    )
    AS c2
    ON cc.ParentId = c2.CommentId

此查询基本上执行以下操作:

  • 获取作为顶级评论的前10条记录,并拥有 特定所有者ID。
  • 获取父ID等于注释ID的所有注释 由第一个查询返回,并将它们与结果集联合。

虽然,我认为这个查询比为每条记录多次调用数据库更有效,但它仍然存在执行第一次查询两次的缺陷。一次在工会之前,一次在工会的加入。

它似乎相当快,但没有我想要的那么快。但是,如果您的数据库是远程的,并且延迟是一个问题,那么此解决方案可能比为数据库进行多个远程查询更好。

答案 3 :(得分:0)

我终于根据Greg Adamskis暗示来管理它......所以不要投我的答案,但要检查一下!!!

简要描述问题...我们需要在我们的网站上对评论列表进行分页。使用标准限制可能会导致某些注释永远不会显示...我们需要的是一个限制,它只会影响我们的父节点,而不会影响回复的cild节点...很长的故事...但是有一次这个iis很有用对于某人:

    function getComments($comment_parent_id, $scope,&$comments, $db)
    {
        $res = $db->select("SELECT * FROM comments WHERE comment_post_id = '{$_REQUEST["ID"]}' AND comment_parent_id = '{$comment_parent_id}' ORDER BY comment_date DESC LIMIT {$scope}");

        while ($row = mysql_fetch_array($res, MYSQL_ASSOC)) 
        {
            $i = count($comments)+1;

            foreach ($row as $k => $v) {
                $comments[$i][$k] = $v;
            }

            //LOOK FOR REPLIES (childs of parent)
            if (mysql_num_rows($db->select("SELECT * FROM comments WHERE comment_parent_id = '{$row['comment_id']}' LIMIT 1")) != 0 ){
                getComments($row['comment_id'],100,$comments,$db);
            }
        }
    }

    //ARGUMENTS: parent_id (always starting with zero), scope, array holding comments, db class
    getComments(0,5,$comments,$db);