根据父ID的mysql排序类别

cic*_*man 11 mysql sql

这是表结构

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有一个id8,而不是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,具体取决于您希望子项的排序方式.

  • @cicakman:我同意......我认为这根本不是一个糟糕的问题.不知道为什么你会受到如此多的批评. (3认同)