繁体   English   中英

在mySQL中从所有父母中选择所有孩子

[英]Selecting All Children From All Parents in mySQL

我有一个这样的简单表格:

+------------+---------+-----------+--------------+
| comment_id | post_id | parent_id | comment_text |
+------------+---------+-----------+--------------+
|          1 |     200 |         0 |          a   |
|          2 |     200 |         0 |          b   |
|          3 |     200 |         1 |          c   |
|          4 |     200 |         1 |          d   |
|          5 |     200 |         0 |          e   |
|          6 |     200 |         2 |          f   |
|          7 |     200 |         2 |          g   |
|          8 |     200 |         0 |          h   |
|          9 |     200 |         0 |          i   |
|         10 |     200 |         1 |          k   |
+------------+---------+-----------+--------------+
  • 列parent_id告诉我们此评论是对此id的另一个评论的回复。

  • 假设只有一个级别的注释嵌套。

现在我只需返回前5条父评论和所有属于它们的孩子。

我有一个查询,但有一个问题。

    (
     SELECT c.* 
     FROM comments AS c 
     WHERE c.post_id = '200' AND parent_id='0'
     LIMIT 0,5
    )
    UNION 
    (
     SELECT c.*
     FROM comments AS c
     WHERE c.post_id = '200' AND c.parent_id IN 
     (
      SELECT c.comment_id
      FROM comments AS c 
      WHERE c.post_id= '200' AND parent_id='0'
      LIMIT 0,5
     )
    )

问题是我当前的mySQL版本在子查询中不支持LIMIT。 似乎我两次执行相同的SELECT查询!

我敢肯定必须有办法更优雅地做到这一点。

最后,我最终使用了Andomar建议但没有子查询的东西:

        (
        select  *
        from    comments c
        where   c.post_id = '200' 
                and c.parent_id = 0
        order by comment_id DESC limit 0, 4
        )
union
       (
        select  *
        from    comments c
        join    comments p
        on      c.parent_id = p.comment_id
        where   c.post_id = '200' 
                and c.parent_id != '0'
        )
        order by comment_id DESC

编辑:正如niaher正确指出的那样,这个查询返回的结果集比需要的大得多。 这使得这个解决方案错了。

幸运的是,我找到了另一种方法,更优雅,更清洁。

正确的方法:

SELECT c.*
    FROM (
        SELECT comment_id
        FROM comments
        WHERE post_id = 200 AND parent_id = 0
        ORDER BY comment_id ASC
        LIMIT 0,5       
    ) AS q
JOIN comments AS c
    ON c.comment_id = q.comment_id OR c.parent_id = q.comment_id

我已经测试了这个查询,它比前一个查询运行得更快。

这是最优雅的方式: http//mikehillyer.com/articles/managing-hierarchical-data-in-mysql/ 您将遇到的一个问题是,插入需要一些时间,因为其他行需要更新; 然而,这可以通过一些创造力来避免。 那篇文章是一个很好的开始。

你能做2次选择吗?

Select * from comments where parentID = 0 limit 5

select * from comments where parentID IN (*list of the 5 parentIDs)

在我的MySQL版本中,您可以在子查询中使用limit:

select  *
from    (
        select  *
        from    comments c
        where   c.post_id = '200' 
                and c.parent_id = 0
        limit    0, 3
        ) s
union
select  c.*
from    (
        select  *
        from    comments c
        where   c.post_id = '200' 
                and c.parent_id = 0
        limit    0, 3
        ) p
join    comments c
on      c.parent_id = p.comment_id;

如果没有MySQL不支持的with语句,重复选择很难避免。 您可以创建一个临时表来存储它们:

drop table if exists top5comments;

create table top5comments
    select  *
    from    comments c
    where   c.post_id = '200' 
            and c.parent_id = 0
    limit    0, 3;

insert  top5comments
select  children.*
from    top5comments parents
join    comments children
on      children.parent_id = parents.comment_id;

select * from top5comments;

如果查询可以同时由多个连接运行,则需要进行修改。

PS顺便说一句, limit声明通常伴随着order by子句。 如果没有order by ,您将获得任意行,结果可能因查询而异。

也许你的意思是:

SELECT
  *,
  (CASE WHEN parent_id = 0 THEN comment_id ELSE parent_id END) AS use_id
FROM
  comments
WHERE
  (CASE WHEN parent_id = 0 THEN comment_id ELSE parent_id END) IN (
    SELECT    comment_id
    FROM      comments
    WHERE     parent_id = 0
    ORDER BY  comment_id ASC
    LIMIT     3)
ORDER BY
  use_id ASC,
  parent_id;

它的作用是取三个'first'(由comment_id ASC排序)父评论及其所有孩子,然后按parent- / comment_id排序整个列表(父母优先,孩子之后)。

例如,那么ELSE END用于SQLite(这就是我测试这些东西的方式)。

- 编辑

如果存在这些记录(超过10个记录):

comment_id  post_id  parent_id  comment
1           200      0          a
2           200      0  b
3           200      1  c
4           200      1  d
5           200      0  e
6           200      2  f
7           200      2  g
8           200      0  h
9           200      0  i
10          200      1  j
11          200      1  k
12          200      2  l
13          200      0  m
14          200      1  n

这将是结果:

comment_id  post_id parent_id   comment use_id
1        200    0   a   1
3        200    1   c   1
4        200    1   d   1
10       200    1   j   1
11       200    1   k   1
14       200    1   n   1
2        200    0   b   2
6        200    2   f   2
7        200    2   g   2
12       200    2   l   2
5        200    0   e   5

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM