我有以下代码,我想用CTE进行递归并在内部递增变量,以便递归可以使用它来执行子查询。
WITH cte as
(
select @layer as layers,
case when exists(select * from #table where layer=@layer and string in ('abc','xyz)) then 10 else 0 end
union all
select layers + 1, total
from cte
where layers + 1<4 -- 4 is a max number that is unknown and given by the user
)select * from cte
#table具有以下结构,但数据量是动态的
string layer
abc 1
xyz 1
abc 2
xyz 2
所以在第1层,如果它有&#39; abc&#39;或者&#39; xyz&#39;它将具有10分,第2层也会发生相同的事情,直到用户给出的最大层为止。我想从递归中得到点和相应的级别。虽然循环和光标是禁止的。我在递归中增加@layer时遇到了麻烦。有什么建议吗?感谢
答案 0 :(得分:2)
我从来没有看到过递归中使用的变量,但我认为你可以用理货表做你想做的事。
if object_id('tempdb..#table') is not null drop table #table
create table #table (string varchar(64), layer int)
insert into #table
values
('abc',1),
('abc',2),
('xyz',2),
--missing layer 3
--missing layer 4
('fgh',5), --not in the abc or xyz clause
('abc',6),
('xyz',7) --greate than the max passed in via @layer
declare @layer int = 6
;WITH
E1(N) AS (select 1 from (values (1),(1),(1),(1),(1),(1),(1),(1),(1),(1))dt(n)),
E2(N) AS (SELECT 1 FROM E1 a, E1 b), --10E+2 or 100 rows
E4(N) AS (SELECT 1 FROM E2 a, E2 b), --10E+4 or 10,000 rows max
cteTally(N) AS
(
SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) FROM E4
)
select
N as Layer
,case when max(layer) is not null then 10 else 0 end
from
cteTally
full join #table
on N = layer and string in ('abc','xyz')
where N <= @layer
group by N
order by N
如果你真的开始使用递归,如果传入的@layer或最大数量很大,这可能会慢得多,那么这就是你将如何实现这一点。
declare @layer int = 6
;with cte as(
select
1 as layer
,total = case when exists(select * from #table t2 where t2.layer=layer and t2.string in ('abc','xyz')) then 10 else 0 end
union all
select
layer + 1
,total = case when exists(select * from #table t2 where t2.layer=c.layer + 1 and t2.string in ('abc','xyz')) then 10 else 0 end
from cte c
where layer < @layer)
select distinct
layer
,total = max(total)
from cte
group by layer
order by layer