使用MySQL选择父级和子级

11

我知道这个问题经常被提出,但今天我找不到我要找的答案。我有一个具有以下架构的表。

CREATE TABLE `comments` (
    `id` bigint(10) unsigned not null auto_increment,
    `parent_id` bigint(10) unsigned default 0,
    `date_sent` datetime not null,
    `content` text not null,
    PRIMARY KEY(`id`)
) ENGINE=InnoDB;

我想选择父行以及这些行的子项。我不允许子项有子项,所以每个父项只有任意数量的子项。

我认为可以使用联合或内部连接来完成此操作。

3个回答

25

父级记录没有 parent_id
子级记录的parent_id等于父级评论的id

  SELECT ...
    FROM comments AS parent
         LEFT JOIN comments AS child 
         ON child.parent_id = parent.id
   WHERE parent.parent_id IS NULL
ORDER BY parent.id, child.id;

请注意,自连接应该是外连接,这样您就不会错过没有子评论的父评论。


谢谢,a1ex07。我想你是指没有子评论的父评论;-) 我认为你还应该在WHERE子句中添加:p.parent_id IS NULL。干杯。 - mechanical_meat
2
如果我有子级到子级的关系,那么我不需要多个连接吗? - Dejell

4

您正在寻找

SELECT p.id, child.*
FROM comments p
INNER JOIN comments child ON (child.parent_id = p.id)
WHERE ....

更新
或者左连接如果你想查看没有父级的行


2
如果我有子级到子级怎么办?难道我不需要多个连接吗? - Dejell
我想限制查找父级的范围,如何设置限制呢? - Anirudha Gupta
当我尝试这样做时,MySQL会抛出错误:ON子句中的未知列。引用p.id列。我的表不同,但逻辑相同,如果没有这个错误,我无法在JOIN子句中使用外部列(来自FROM子句)。帮帮我! - Jhonatan Pereira

2

我并没有说得很明确,我认为你遇到了以下这种问题:

Ordered_Item(已订购的项目)

ID | Item_Name
1  | Pizza
2  | Stromboli

有序选项

Ordered_Item_ID | Option_Number | Value
        1               43         Pepperoni
        1               44         Extra Cheese
        2               44         Extra Cheese

输出

ID | Item_Name | Option_1 | Option_2
1    Pizza       Pepperoni  Extra Cheese
2    Stromboli     NULL     Extra Cheese

我建议使用以下方法解决这个问题:

  1. 最简单的方法是使用GROUP_CONCAT组函数。
select 
        ordered_item.id as `Id`, 
        ordered_item.Item_Name as `ItemName`,

  GROUP_CONCAT(Ordered_Options.Value) as `Options`

  from ordered_item, ordered_options

  where ordered_item.id=ordered_options.ordered_item_id

  group by ordered_item.id

这将产生以下输出:

Id              ItemName       Options
1               Pizza          Pepperoni,Extra Cheese
2               Stromboli      Extra Cheese

这样,您就可以拥有尽可能多的选项,而无需修改查询。

如果您发现结果被裁剪,可以像这样增加GROUP_CONCAT的大小限制:

SET SESSION group_concat_max_len = 8192;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接