在 SQL 服务器中对分层 table 进行排序?
Sort Hierarchical table in SQL Server?
我有一个 table Address 我想对行进行排序 parent-1 => all-child-parent-1, parent -2 => all-child-parent-2 依此类推....
地址Table
ID Caption Parent
---------------------
1 A NULL
2 B NULL
3 a 1
4 b 2
5 bb 4
6 C NULL
7 aa 3
8 c 6
NULL Parent is is mean Root
期望的输出
ID Sort Caption Parent
---------------------------
1 1 A NULL
3 2 a 1
7 3 aaa 3
2 4 B NULL
4 5 b 2
5 6 bb 4
6 7 C NULL
8 8 c 6
这种排序需要以某种方式遍历层次结构来计算每个节点的路径。
您可以使用递归查询来执行此操作:
with cte as (
select id, caption, parent, caption addr
from mytable
where parent is null
union all
select t.id, t.caption, t.parent, c.addr + '/' + t.caption
from cte c
inner join mytable t on t.parent = c.id
)
select
id,
row_number() over(order by addr) sort,
caption,
parent
from c
order by addr
您可以构造每一行的路径,然后使用它进行排序。该构造使用了递归 CTE:
with cte as (
select id, caption, parent, convert(varchar(max), format(id, '0000')) as path, 1 as lev
from t
where parent is null
union all
select t.id, t.caption, t.parent, convert(varchar(max), concat(path, '->', format(t.id, '0000'))), lev + 1
from cte join
t
on cte.id = t.parent
)
select id, caption, parent
from cte
order by path;
Here 是一个 db<>fiddle.
不需要递归,只需使用一些巧妙的排序!
SELECT
ID,
ROW_NUMBER() over(order by Caption) as Sort,
Caption,
Parent
FROM Address
ORDER BY Caption, Parent
SQL Fiddle: http://sqlfiddle.com/#!18/bbbbe/9
还有一种选择是使用 hierarcyid
数据类型
例子
Declare @YourTable Table ([ID] int,[Caption] varchar(50),[Parent] int) Insert Into @YourTable Values
(1,'A',NULL)
,(2,'B',NULL)
,(3,'a',1)
,(4,'b',2)
,(5,'bb',4)
,(6,'C',NULL)
,(7,'aa',3)
,(8,'c',6)
;with cteP as (
Select ID
,Parent
,Caption
,HierID = convert(hierarchyid,concat('/',ID,'/'))
From @YourTable
Where Parent is null
Union All
Select ID = r.ID
,Parent = r.Parent
,Caption = r.Caption
,HierID = convert(hierarchyid,concat(p.HierID.ToString(),r.ID,'/'))
From @YourTable r
Join cteP p on r.Parent = p.ID)
Select Lvl = HierID.GetLevel()
,ID
,Parent
,Caption
From cteP A
Order By A.HierID
Returns
Lvl ID Parent Caption
1 1 NULL A
2 3 1 a
3 7 3 aa
1 2 NULL B
2 4 2 b
3 5 4 bb
1 6 NULL C
2 8 6 c
我有一个 table Address 我想对行进行排序 parent-1 => all-child-parent-1, parent -2 => all-child-parent-2 依此类推....
地址Table
ID Caption Parent
---------------------
1 A NULL
2 B NULL
3 a 1
4 b 2
5 bb 4
6 C NULL
7 aa 3
8 c 6
NULL Parent is is mean Root
期望的输出
ID Sort Caption Parent
---------------------------
1 1 A NULL
3 2 a 1
7 3 aaa 3
2 4 B NULL
4 5 b 2
5 6 bb 4
6 7 C NULL
8 8 c 6
这种排序需要以某种方式遍历层次结构来计算每个节点的路径。
您可以使用递归查询来执行此操作:
with cte as (
select id, caption, parent, caption addr
from mytable
where parent is null
union all
select t.id, t.caption, t.parent, c.addr + '/' + t.caption
from cte c
inner join mytable t on t.parent = c.id
)
select
id,
row_number() over(order by addr) sort,
caption,
parent
from c
order by addr
您可以构造每一行的路径,然后使用它进行排序。该构造使用了递归 CTE:
with cte as (
select id, caption, parent, convert(varchar(max), format(id, '0000')) as path, 1 as lev
from t
where parent is null
union all
select t.id, t.caption, t.parent, convert(varchar(max), concat(path, '->', format(t.id, '0000'))), lev + 1
from cte join
t
on cte.id = t.parent
)
select id, caption, parent
from cte
order by path;
Here 是一个 db<>fiddle.
不需要递归,只需使用一些巧妙的排序!
SELECT
ID,
ROW_NUMBER() over(order by Caption) as Sort,
Caption,
Parent
FROM Address
ORDER BY Caption, Parent
SQL Fiddle: http://sqlfiddle.com/#!18/bbbbe/9
还有一种选择是使用 hierarcyid
数据类型
例子
Declare @YourTable Table ([ID] int,[Caption] varchar(50),[Parent] int) Insert Into @YourTable Values
(1,'A',NULL)
,(2,'B',NULL)
,(3,'a',1)
,(4,'b',2)
,(5,'bb',4)
,(6,'C',NULL)
,(7,'aa',3)
,(8,'c',6)
;with cteP as (
Select ID
,Parent
,Caption
,HierID = convert(hierarchyid,concat('/',ID,'/'))
From @YourTable
Where Parent is null
Union All
Select ID = r.ID
,Parent = r.Parent
,Caption = r.Caption
,HierID = convert(hierarchyid,concat(p.HierID.ToString(),r.ID,'/'))
From @YourTable r
Join cteP p on r.Parent = p.ID)
Select Lvl = HierID.GetLevel()
,ID
,Parent
,Caption
From cteP A
Order By A.HierID
Returns
Lvl ID Parent Caption
1 1 NULL A
2 3 1 a
3 7 3 aa
1 2 NULL B
2 4 2 b
3 5 4 bb
1 6 NULL C
2 8 6 c