总是不鼓励使用游标,它已广泛用于我们当前的存储过程并用基于集合的查询替换它们。但是这个特殊情况是一个,我没有得到使用基于集合的查询的解决方案,并被迫继续使用游标。我在下面提供代表方案的示例代码:
DECLARE @temp varchar(10), @continuechar varchar(10)
DECLARE @table1 table (col1 varchar(10))
insert into @table1
select 'A' UNION
select 'B' UNION
select 'C' UNION
select 'D' UNION
select 'E' UNION
select 'F' UNION
select 'G'
DECLARE Cursor1 CURSOR for select Col1 from @table1
open Cursor1
FETCH NEXT from Cursor1 into @temp
WHILE @@FETCH_STATUS = 0
BEGIN
if @temp='A'
BEGIN
set @continuechar=@temp
END
if @temp='C'
BEGIN
set @continuechar=@temp
END
select @continuechar, @temp
FETCH NEXT from Cursor1 into @temp
END
CLOSE cursor1;
deallocate cursor1
以上示例代码@continuechar变量未设置,每次光标执行时。如果设置了@continuechar,则后面的select语句提供的结果集的当前值为@continuechar:
select @continuechar, @temp
如果未设置,则使用先前设置的值来提供结果集。 我们可以设置基于查询来从这种情况中删除光标。
答案 0 :(得分:0)
首先,我会添加一些id
列以获得稳定排序。然后只需使用窗口函数:
SUM() OVER()
计算群组FIRST_VALUE() OVER()
在组中传播第一个值
(从SQL Server 2012开始,如果需要,您可以与MAX(continuechar) OVER(PARTITION BY grp)
交换)DECLARE @table1 table (id INT IDENTITY(1,1), col1 varchar(10)) insert into @table1 select 'A' UNION select 'B' UNION select 'C' UNION select 'D' UNION select 'E' UNION select 'F' UNION select 'G'; WITH cte AS ( SELECT id ,col1 ,CASE WHEN col1 IN('A', 'C') THEN col1 END AS continuechar ,SUM(CASE WHEN col1 IN ('A', 'C') THEN 1 ELSE 0 END) OVER(ORDER BY id) AS grp FROM @table1 ) SELECT id, col1, FIRST_VALUE(continuechar) OVER(PARTITION BY grp ORDER BY id) AS continuechar FROM cte ORDER BY id;
<强> DBFiddle Demo 强>
修改强>
Quirky update
这仅适用于纯粹演示。不要在生产系统上使用此方法:
DECLARE @table1 table (id INT IDENTITY(1,1) PRIMARY KEY, col1 varchar(10),
continue_char VARCHAR(10));
DECLARE @temp VARCHAR(10);
insert into @table1(col1)
select 'A' UNION
select 'B' UNION
select 'C' UNION
select 'D' UNION
select 'E' UNION
select 'F' UNION
select 'G';
UPDATE @table1
SET @temp = CASE WHEN col1 IN ('A','C') THEN col1 ELSE @temp END
,continue_char = @temp
OPTION(MAXDOP 1);
SELECT *
FROM @table1;
<强> DBFiddle Demo2 强>