在自己引用的表格中向父母展示孩子

时间:2015-06-16 15:40:04

标签: sql oracle

假设我有一个像这样的自引用表

------------------------------
| 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   |          |
------------------------------

在子项适用时显示父项。

2 个答案:

答案 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。