【发布时间】:2020-10-16 06:59:57
【问题描述】:
我正在尝试进行动态查询以通过子-父母表,并且我已经能够通过分层查询的顶层和第二级:
数据:
create table temp
(
Pos int
,Child nvarchar(18)
,Parent nvarchar(18)
,Test int
);
insert into temp (Pos, Child, Parent, Test)
values
(1, 'A', NULL, 1),
(2, 'J', NULL, 10),
(3, 'P', NULL, 16),
(4, 'Y', NULL, 25),
(1, 'B', 'A', 2),
(2, 'E', 'A', 5),
(1, 'C', 'B', 3),
(2, 'D', 'B', 4),
(1, 'F', 'E', 6),
(2, 'G', 'E', 7),
(1, 'H', 'G', 8),
(2, 'I', 'G', 9),
(1, 'K', 'J', 11),
(2, 'L', 'J', 12),
(3, 'M', 'J', 13),
(1, 'N', 'M', 14),
(2, 'O', 'M', 15),
(5, 'Z', NULL, 26),
(1, 'Q', 'P', 17),
(2, 'S', 'P', 19),
(3, 'T', 'P', 20),
(4, 'X', 'P', 24),
(1, 'R', 'Q', 18),
(1, 'U', 'T', 21),
(2, 'V', 'T', 22),
(3, 'W', 'T', 23)
Test 列仅在最后查看数据是否正确排序
到目前为止我的代码:
declare @sql nvarchar(max);
declare @tlp nvarchar(max); --top level parents
declare @i nvarchar(4);
declare @j nvarchar(4);
declare @l nvarchar(4); --level
set @tlp = ';with tlp as (
select ROW_NUMBER() over (order by Pos) as j, * from temp where Parent IS NULL
)';
set @i = 1;
set @j = (select COUNT(*) as j from temp where Parent IS NULL);
set @sql = @tlp;
while @i < @j
begin
set @l = 1;
set @sql += '
select ' + @l + ' as Level, * from tlp where j = ' + @i
set @l = @l + 1
set @sql += '
union all
select ' + @l + ' as Level, ROW_NUMBER() over (order by Pos), * from temp where Parent = (select Child from tlp where j = ' + @i + ')'
set @i = @i + 1
if @i < @j set @sql += '
union all'
end;
exec(@sql);
输出:
level j Pos Child Parent Test
1 1 1 A NULL 1
2 1 1 B A 2
2 2 2 E A 5
1 2 2 J NULL 10
2 1 1 K J 11
2 2 2 L J 12
2 3 3 M J 13
1 3 3 P NULL 16
2 1 1 Q P 17
2 2 2 S P 19
2 3 3 T P 20
2 4 4 X P 24
1 4 4 Y NULL 25
如何扩展查询以动态遍历所有子项?这是所需的输出:
Level j Pos Child Parent Test
1 1 1 A NULL 1
2 1 1 B A 2
3 1 1 C B 3
3 2 2 D B 4
2 2 2 E A 5
3 1 1 F E 6
3 2 2 G E 7
4 1 1 H G 8
4 2 2 I G 9
1 2 2 J NULL 10
2 1 1 K J 11
2 2 2 L J 12
2 3 3 M J 13
3 1 1 N M 14
3 2 2 O M 15
1 3 3 P NULL 16
2 1 1 Q P 17
3 1 1 R Q 18
2 2 2 S P 19
2 3 3 T P 20
3 1 1 U T 21
3 2 2 V T 22
3 3 3 W T 23
3 4 4 X P 24
1 4 4 Y NULL 25
1 5 5 Z NULL 26
这是我试图实现的视觉解释:
【问题讨论】:
-
您不需要动态 SQL 来计算层次查询中的级别。根查询可以返回
1作为级别,递归调用可以增加它。我很确定文档示例显示了这一点 -
能否详细说明您的专栏 j ?它代表什么?你应该怎么计算呢?
-
@JoPapou13 变量 j 背后的想法是获取层次结构中的总列数,从顶级父级 (j = 5) 开始,用于 while 条件和联合选择
标签: sql-server tsql dynamic-sql hierarchical-data recursive-query