T-SQL员工层次递归查询
我想使用一个T-SQL查询,它可以是递归的CTE或任何地方 我可以得到如下突出显示的输出 SQL创建示例表,如下所示T-SQL员工层次递归查询,sql,sql-server,tsql,Sql,Sql Server,Tsql,我想使用一个T-SQL查询,它可以是递归的CTE或任何地方 我可以得到如下突出显示的输出 SQL创建示例表,如下所示 --drop table #hierarchy CREATE TABLE #hierarchy ( ID INTEGER NOT NULL PRIMARY KEY, Value CHAR(10) NOT NULL, ); INSERT INTO #hierarchy VALUES (1, 'a1'), (2, 'b2'), (3, 'c3'), (4, 'd4'
--drop table #hierarchy
CREATE TABLE #hierarchy
(
ID INTEGER NOT NULL PRIMARY KEY,
Value CHAR(10) NOT NULL,
);
INSERT INTO #hierarchy
VALUES (1, 'a1'), (2, 'b2'), (3, 'c3'), (4, 'd4'),
(5, 'e5'), (6, 'f6'), (7, 'g7'), (8, 'h8');
欢迎任何建议,尝试过类似于阶乘操作的递归cte,但将非常感谢您的输入
提前感谢。您似乎正在寻找字符串连接:
select
id,
value,
(
select string_agg(trim(value), '->') within group(order by id)
from #hierarchy h1
where h1.id <= h.id
) path
from #hierarchy h
:
在不支持'string_agg'的SQL Server版本中,您可以:
select
id,
value,
stuff(
(
select distinct '->' + trim(h1.value) val
from #hierarchy h1
where h1.id <= h.id
order by val
for xml path(''), type
).value('.', 'nvarchar(max)')
, 1, 2, ''
) path
from #hierarchy h
您似乎需要累积字符串聚合:
select string_agg(value, '->') over (order by id)
from hierarchy
但是SQLServer不支持这一点。相反,您可以使用交叉应用:
这可以用于重叠字符串,但逻辑有点麻烦
您还可以使用递归CTE:
with cte as (
select h.id, trim(h.value) as value, convert(varchar(max), trim(h.value)) as str
from hierarchy h
where id = 1
union all
select h.id, trim(h.value) as value, cte.str + '->' + trim(h.value) as str
from cte join
hierarchy h
on h.id = cte.id + 1
)
select *
from cte;
这使用了这样一个事实,即ID是连续的,并且没有间隙。如果不能保证这一点,您可以使用row_number生成这样一个数字。我在您的数据中看不到层次结构。假设它是一个简单的增量结构,在这种情况下,1个顶级管理器和8个叶节点员工您在从ID=4开始的所需输出中似乎缺少c3。这有什么原因吗?另外,了解实际的表结构也很好,因为@GordonLinoff指出,您的数据中没有实际的层次结构,提供的答案可能与您实际想要/需要做的事情不符。缺少c3是我的错,然而,正如评论中所提到的,这是一个直接的简单的底层行,报告给直接的先辈感谢快速的响应,SQL server 2008中的任何建议机制没有字符串的任何替代解决方案请没有字符串的替代方案请?@Sethu。为什么不呢?
select h.*, h2.str
from hierarchy h cross apply
(select string_agg(trim(value), '->') within group (order by id) as str
from hierarchy h2
where h2.id <= h.id
) h2
select h.*, s.str,
left(s.str, patindex('%' + trim(h.value) + '%', s.str) + len(trim(h.value)) - 1)
from hierarchy h cross join
(select string_agg(trim(value), '->') within group (order by id) as str
from hierarchy
) s;
with cte as (
select h.id, trim(h.value) as value, convert(varchar(max), trim(h.value)) as str
from hierarchy h
where id = 1
union all
select h.id, trim(h.value) as value, cte.str + '->' + trim(h.value) as str
from cte join
hierarchy h
on h.id = cte.id + 1
)
select *
from cte;