这是表结构
id parent_id name
1 0 BMW
2 0 Mercedez
3 0 Porsche
4 1 3 Series
5 2 E60
6 1 5 Series
7 3 Cayenne
Run Code Online (Sandbox Code Playgroud)
我怎样才能把桌子展示出来
BMW
3 Series
5 Series
Mercedez
E60
Porsche
Cayenne
Run Code Online (Sandbox Code Playgroud)
上表显示了升序id,后跟与该id相关联的parent_id,然后转到第二个ID,依此类推.我需要在一个查询中,是否可以这样做?
Tra*_*ty3 20
试试这个:
SELECT
name,
CASE WHEN parent_id = 0 THEN id ELSE parent_id END AS Sort
FROM
cars
ORDER BY
Sort,
id
Run Code Online (Sandbox Code Playgroud)
http://sqlfiddle.com/#!2/9b05f/3
鉴于这个答案不断得到提升,我重新审视了这个问题并找到了一个缺陷.如果由于某种原因,父母的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
Run Code Online (Sandbox Code Playgroud)
注意,现在BMW有一个id的8,而不是1.结果将如下所示:
Mercedez
E60
Porsche
Cayenne
3 Series
5 Series
BMW
Run Code Online (Sandbox Code Playgroud)
请注意,宝马出现在名单的最底层,在其子女之后!这是因为二级排序依次排序id,如果父级ID恰好高于任何子级,则父级可能不会显示在子级之上.
此查询将解决该问题:
SELECT
name
FROM
cars
ORDER BY
CASE WHEN parent_id = 0 THEN id ELSE parent_id END, -- another way of writing it: ISNULL(NULLIF(parent_id, 0), id)
parent_id,
id
Run Code Online (Sandbox Code Playgroud)
http://sqlfiddle.com/#!2/6d6d73/3
要解释这里发生了什么,首先按父行的id字段和子行的parent_id字段排序.如果您按此顺序,所有孩子将与他们的父母分组,整个列表将由父母的id字段排序.
但是这并没有在家庭中设置排序,因此父母可以在家庭中的任何地方出现(父母可以出现在顶部,或者可以在中间,或者可能是最后).
这就是其他两个排序字段的位置.第二个字段按顺序排序parent_id,父行的parent_id字段始终排序0.安全地假设您的ID字段始终为正,这意味着父记录将始终显示在系列中的顶部.其余的孩子都具有相同的值parent_id,因此第三个排序字段按字段对家庭中的孩子进行排序id.这也可以更改为name,具体取决于您希望子项的排序方式.