按父ID的顺序选择记录

时间:2010-11-23 18:01:06

标签: mysql

简单的问题..无法按照我需要的顺序得到结果集:p

我有一个表“类别”

id    | name     | parent
1       apple      0
2       macintosh  1
3       atari      0
4       st         3
5       lisa       1

我正在尝试选择获取以下结果集:

1   apple      0
5   lisa       1
2   macintosh  1
3   atari      0
4   st         3

所以换句话说,我想要所有行的所有列,其中带有父项的行紧跟在其父行之后,并且所有行都按字母顺序排序。

parent a
 child a
 child b
parent b
 child a

我现在使用的查询没有正确地在其父级之后重新排序行

SELECT a.*, b.* FROM categories a RIGHT JOIN categories b ON b.parent = a.id

4 个答案:

答案 0 :(得分:13)

如果没有父母的人null列中有parent,那么您的陈述会非常简单:

SELECT id, name, parent FROM categories order by coalesce(parent, id), id;

如果你坚持0代表没有父母,你可以使用更详细的CASE WHEN ... THEN ...陈述。

编辑:

-- Sorting by name instead
select a.id, a.name, a.parent 
from categories a left join categories b on a.parent=b.id 
order by coalesce(b.name, a.name), a.name

答案 1 :(得分:5)

对于一个简单的,可能是次优的,可扩展的解决方案,我建议您使用最大级别对其进行硬编码:

仅限2个级别:

SELECT p2.name as `Parent name`, p1.*
FROM categories p1
LEFT JOIN categories p2 on p1.categories_id = p2.id

你真的在询问排序,所以我建议生成一个类似“路径”的字符串: (请参阅下面的查询示例输出)

SELECT Concat(If(isnull(p2.name),"",Concat("/",p2.name)),"/",p1.name) as `generated path`, p2.name as `Parent name`, p1.*
FROM categories p1
LEFT JOIN categories p2 on p1.parent_id = p2.id
order by `generated path`

对于3个级别,虽然你的数据还没有这个 - 路径被省略,因为它会变丑:)

SELECT p3.name as `Grandparent name`, p2.name as `Parent name`, p1.*
FROM categories p1
LEFT JOIN categories p2 on p1.categories_id = p2.id
LEFT JOIN categories p3 on p2.categories_id = p3.id

一个更全面的解决方案,用于快速选择任何级别的特定类别中的所有项目,这需要对所有写入进行一些工作,正在实施'right' and 'left' numbering concept。但是,对此的进一步讨论几乎肯定超出了你所要求的范围。然而,这是我的经验中唯一一个很好的方法,使这种自引用表非常有用,如果它会变大(可能在1000行以上有3到10级)。

附录:第二个查询的示例输出:

generated path         Parent name         id         name         parent_id
----------------------------------------------------------------------------
/apple                                      1         apple                0
/apple/lisa                  apple          5         lisa                 1
/apple/mac                   apple          2         mac                  1
/atari                                      3         atari                0
/atari/st                    atari          4         st                   3

答案 2 :(得分:2)

这可行,但不能递归。

SELECT 
  b.* 
FROM
  categories a 
  RIGHT JOIN categories b ON b.parent = a.id
ORDER BY
  COALESCE(a.name, b.name), b.name

答案 3 :(得分:0)

看看是否有效:

SELECT Table1.ID, Table1.name, Table1.parent, Table1_1.name, Table1_1.parent
FROM Table1 INNER JOIN Table1 AS Table1_1 ON Table1.ID = Table1_1.parent
ORDER BY Table1.name;

我使用Micorsoft Access构建了它,它看起来就像你想要的那样。我认为您需要一份报告,以便在视觉上向您提供您希望提供给消费者的内容,但为了正确加入以达到这一点,这是有效的。