按多列排序的订单行选择

5

我有一个数据库

id    |     parentid     |       name
1     |        0         |      CatOne
2     |        0         |      CatTwo
3     |        0         |      CatThree
4     |        1         |      SubCatOne
5     |        1         |      SubCatOne2
6     |        3         |      SubCatThree

我该如何选择按照idparentid排序的这些猫?

CatOne 1
--SubCatOne 4
--SubCatOne2 5
CatTwo 2
CatThree 3
--SubCatThree 6

@a_horse_with_no_name,抱歉,MySQL。 - Isis
嵌套的父级连接是否更深层,还是只有两层层次结构? - DRapp
5个回答

5
假设你的表名为cats,尝试使用以下方法:
select * from  cats
order by
      case when parentid = 0 then id else parentid end,
      case when parentid = 0 then 0 else id end

更新以包括当父元素的id大于子元素时的情况


是的,这个方法可以运行... 但是我有一个顾虑。如果这是在自动递增表中,而子类别被重新分类到比它的ID更高的类别号码,那么子类别将出现在其相应的父类别之上... - DRapp

3
这应该可以做到...除了名称前面的双破折号“--”之外...
SELECT 
      t1.name,
      t1.id
   FROM 
      Table1 t1
   ORDER BY 
      case when t1.parentID = 0 then t1.ID else t1.ParentID end,
      case when t1.parentID = 0 then '1' else '2' end,
      t1.id

按FIRST case/when排序会将所有处于顶层或次级别的项目按照主级别ID排列。因此,如果您有超过1000个条目,尝试使用父*1000样本hack不会成为问题。第二个case/when将强制将父ID=0的项置于其分组列表的顶部,并将其所有子项放在其下,但在下一个父ID之前。

然而,如果您确实想要双破折号,请更改为

SELECT 
      if( t1.ParentID = 0, '', '--' ) + t1.name name,
     <rest of query is the same>

1

这个:

select id as parentId,
0 as sortOrder,
id,
name
from cats 
where parentId = 0
union all
select parentId,
1 as sortOrder,
id,
name
from cats 
where parentId > 0
order by parentId, sortOrder, name

返回:
ParentId sortOrder  id   Name
    1       0       1   CatOne
    1       1       4   SubCatOne
    1       1       5   SubCatOne2
    2       0       2   CatTwo
    3       0       3   CatThree
    3       1       6   SubCatThree

如果在ParentId上有索引,那么就不会出现这种情况。在过去的11年中,在不到100,000行的表中,我从未遇到选择操作需要超过1秒钟的情况。 - JBrooks

1

如果您按以下方式排序:ORDER BY parentid,id

那么您将获得您要查找的顺序,但它不会被意图或任何东西所打乱,就像您的示例一样。

SQL可能不是做缩进分组的最佳媒介。您可以...但最好在前端应用程序中完成

编辑:抱歉误读问题,Eric Petroelje所说的。

编辑编辑:或者从表中选择,加入自身(一个用于Cat,一个用于SubCat),然后指定不同的排序,每个表一个。


0
你可以尝试这个。它不完全符合你指定的格式,但是否符合你的要求?
SELECT c.id,c.name,sc.id as subcatid,sc.name as subcatname
FROM cats c LEFT JOIN cats sc ON c.id=sc.parentid
WHERE c.parentid=0 order by c.id,sc.id;

它会产生以下结果:
+------+----------+----------+-------------+
| id   | name     | subcatid | subcatname  |
+------+----------+----------+-------------+
|    1 | CatOne   |        4 | SubCatOne   |
|    1 | CatOne   |        5 | SubCatOne2  |
|    2 | CatTwo   |     NULL | NULL        |
|    3 | CatThree |        6 | SubCatThree |
+------+----------+----------+-------------+

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接