假设我有一个像这样的自引用表
------------------------------
| ID | Name | ParentID |
| 1 | Fruits | |
| 2 | Vegetables | |
| 3 | Animals | |
| 4 | Whatever | |
| 6 | Orange | 1 |
| 7 | Apple | 1 |
| 8 | Banana | 1 |
------------------------------
我需要进行查询才能检索数据,如下所示:
------------------------------
| ID | Name | ParentID |
| 1 | Fruits | |
| 6 | Orange | 1 |
| 7 | Apple | 1 |
| 8 | Banana | 1 |
| 2 | Vegetables | |
| 3 | Animals | |
| 4 | Whatever | |
------------------------------
在子项适用时显示父项。
答案 0 :(得分:2)
假设您正在使用某些SQL Server变体,您需要使用包含某种路径/ breadcrumb列的公用表表达式...
;with cte as
(
select Id, Name, ParentID,
convert(nvarchar(max), [Id]) as Breadcrumb
from dbo.Location
where ParentID is null
--
union all
--
select l.Id, l.Name, l.ParentID,
cte.BreadCrumb + '\' + convert(nvarchar(max), l.[Id]) as Breadcrumb
from dbo.Location l
inner join cte on l.ParentId = cte.Id
)
select *
from cte
order by Breadcrumb
修改:您可以使用ID或名称作为面包屑值 - 取决于您希望如何对数据进行实际排序。
答案 1 :(得分:0)
如果是SQL server:
select * from MyTable
order by
case when ID in (select distinct parentID from MyTable)
then ID - 0.5 else isnull(parentID, 100000) end
, ID
检查ID是否为父级 - 如果是,则将其排序到将其作为父级的记录之上(通过从ID中减去0.5)。
注意:isnull(parentID, 100000)
只是一个任意大的值,用于删除既不是父级也没有父级到列表底部的行 - 根据您的数据根据需要进行调整。如果您有大量数据和/或它经常更改,您可能希望使用基于表中最大ID的计算值替换100,000。