尝试这个:
SELECT
name,
CASE WHEN parent_id = 0 THEN id ELSE parent_id END AS Sort
FROM
cars
ORDER BY
Sort,
id
http://sqlfiddle.com/#!2/9b05f/3
编辑:
鉴于这个答案不断得到支持,我重新审视了这个问题并发现了一个缺陷。如果由于某种原因,父母的 ID 比孩子的 ID 高,那么排序就会混乱。仅当父 ID 小于所有子 ID 时,上述查询才有效。
为了演示这个问题,假设表格如下所示:
id parent_id name
8 0 BMW
2 0 Mercedez
3 0 Porsche
4 8 3 Series
5 2 E60
6 8 5 Series
7 3 Cayenne
注意现在有BMW
一个8而不是1。结果将如下所示:id
Mercedez
E60
Porsche
Cayenne
3 Series
5 Series
BMW
请注意,BMW出现在列表的底部,在它的孩子之后!这是因为二次排序按 排序id
,如果父 ID 恰好高于任何子 ID,则父 ID 可能不会显示在子 ID 之上。
此查询将解决该问题:
SELECT
name
FROM
cars
ORDER BY
CASE WHEN parent_id = 0 THEN id ELSE parent_id END, -- another way of writing it: IFNULL(NULLIF(parent_id, 0), id)
parent_id,
id
http://sqlfiddle.com/#!2/6d6d73/3
为了解释这里发生了什么,您首先按父行的id
字段和子行的字段进行排序parent_id
。如果您按此排序,则所有子级将与其父级分组,并且整个列表将按父级id
字段排序。
但这并没有设置家庭内的排序,因此父母可以出现在家庭中的任何地方(父母可以出现在顶部,或者它可能在中间,或者它可能是最后一个)。
这就是其他两个排序字段的来源。第二个字段按 排序parent_id
,父行的parent_id
字段始终为0
。安全地假设您的 ID 字段始终为正,这意味着父记录将始终显示在家庭中的顶部。其余的孩子都将具有相同的值parent_id
,因此第三个排序字段按其id
字段对家庭中的孩子进行排序。这也可以更改为name
,具体取决于您希望孩子如何排序。