简单的问题..无法按照我需要的顺序得到结果集: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
答案 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构建了它,它看起来就像你想要的那样。我认为您需要一份报告,以便在视觉上向您提供您希望提供给消费者的内容,但为了正确加入以达到这一点,这是有效的。