MySQL自我加入有限的层次结构

时间:2015-02-13 09:22:35

标签: mysql sql hierarchy self-join

嗨我有一个自我加入的MySQL表我正在用于评论和回复。

CREATE TABLE comments (id INT, parent_id INT, comment VARCHAR(50));

INSERT INTO comments VALUES
 (1,     0,           'comment 1'            ),
 (2,     0,           'comment 2'            ),
 (3,     0,           'comment 3'            ),
 (4,     1,           'comment 1 - reply 1'  ),
 (5,     0,           'comment 4'            ),
 (6,     3,           'comment 3 - reply 1'  ),
 (7,     1,           'comment 1 - reply 2'  ),
 (8,     0,           'comment 5'            );

只有一个级别的回复。也就是说,回复只能与顶级注释相关联(其中parent_id = 0)。

我使用以下查询来显示每个顶级注释(其中parent_id = 0)和每个注释相关的回复。

SELECT *
FROM comments 
ORDER BY IF(parent_id = 0, id, parent_id) desc , parent_id != 0, id desc

输出:

id  parent_id   comment
-------------------------
8      0        comment 5
5      0        comment 4
3      0        comment 3
6      3        comment 3 - reply 1
2      0        comment 2
1      0        comment 1
7      1        comment 1 - reply 2
4      1        comment 1 - reply 1

当前查询适用于我需要的内容。

我的问题是如何限制每条评论的回复数量?例如。显示最新的50个顶级评论,每条评论最多回复2个。

Here is a SqlFiddle if it helps

2 个答案:

答案 0 :(得分:1)

试试这个:

修改

SELECT pc.id,
       pc.parent_id,
       pc.comment
  FROM (
          SELECT id,
                 parent_id,
                 comment,
                 @parentRank := @parentRank + 1 AS rank
            FROM comments,
                 (SELECT @parentRank := 0) pcr
           WHERE parent_id = 0
        ORDER BY id DESC                      
       ) pc
 WHERE pc.rank <= 5
 UNION
SELECT cc.id,
       cc.parent_id,
       cc.comment
  FROM (
          SELECT id,
                 parent_id,
                 comment,
                 @childRank := if(@current_parent_id = parent_id, @childRank + 1, 1) AS rank,
                 @current_parent_id := parent_id
            FROM comments,
                 (SELECT @childRank := 0) cr
           WHERE parent_id in (
                                SELECT id
                                  FROM (
                                         SELECT id,
                                                @parentRank := @parentRank + 1 AS rank
                                           FROM comments,
                                                (SELECT @parentRank := 0) pcr
                                          WHERE parent_id = 0
                                       ORDER BY id DESC                      
                                       ) pc
                                 WHERE pc.rank <= 5
                              ) 
        ORDER BY parent_id DESC,
                 id DESC
             ) cc
       WHERE cc.rank <= 1
ORDER BY IF(parent_id = 0, id, parent_id) desc , parent_id != 0, id desc

我在SQLFiddler

中做了一个演示

答案 1 :(得分:0)

限制(偏移)的第一个参数控制回复数量

SELECT *, 

(SELECT COUNT(id) FROM comments r where r.parent_id = c.id) AS number_of_replies

FROM comments c

WHERE IFNULL((SELECT e.id FROM comments e WHERE e.parent_id != 0 AND 
    e.parent_id = c.parent_id ORDER BY e.id DESC LIMIT 2, 1), 0) < c.id

ORDER BY IF(parent_id = 0, id, parent_id) desc , parent_id != 0, id desc