Sql server 2005 使用CTE代替光标

Sql server 2005 使用CTE代替光标,sql-server-2005,tsql,cursor,common-table-expression,cross-apply,Sql Server 2005,Tsql,Cursor,Common Table Expression,Cross Apply,我有下面的表结构 我只想将SubId更新到所有行,其中SubId为null,RAWLINENNUMBER升序为1,SeqNumber升序为1 RawlineNumber Claimid SubId SeqNumber 1 6000 A100 1 2 6000 NULL 2 3 6000 NULL 3 10 6000 A200 1 11 6000

我有下面的表结构

我只想将SubId更新到所有行,其中SubId为null,RAWLINENNUMBER升序为1,SeqNumber升序为1

RawlineNumber Claimid SubId SeqNumber
1             6000    A100  1
2             6000    NULL  2
3             6000    NULL  3
10            6000    A200  1
11            6000    NULL  2
25            6000    A300  1
26            6000    NULL  2
27            6000    NULL  3
我想更新一下 带A100的原始线编号2和3的子ID, 带A200的11号粗线条的子ID, 原始线条编号26和27的子ID,带有A300


我有一个光标,它可以完成这项工作,但是我可以用一个CTE来处理它吗?

一个不那么简单的SQL脚本应该可以实现您想要的:

update my_table t1 set t1.subid = 
  (select t2.subid from my_table t2 
   where t2.rawlinenumber < t1.rawlinenumber
   and t2.seqnumber = 1
   and t2.rawlinenumber = (
                   select max(t3.rawlinenumber)
                   from my_table t3 
                   where t3.seq_number = 1
                   and t3.rawlinenumber <= t2.rawlinenumber)
where t1.subid is null;
内部子选择T3给出了当前行之前seqnumber=1的最后一行,
外部subselect为我们提供了此行的SubID,使用窗口函数将更有效,但由于您没有提到特定的RDBMS,我坚持这样做:-

由于请求了一个递归解决方案,我决定编写一个。它还适用于SeqNumber和RawlineNumber中的间隙

UPDATE  m
SET     subid = q.subid 
FROM    mytable m
CROSS APPLY
        (
        SELECT  TOP 1 subid 
        FROM    mytable mi
        WHERE   mi.rawLineNumber  < m.rawLineNumber 
                AND mi.subid IS NOT NULL
        ORDER BY
                rawLineNumber DESC
        ) q
WHERE   m.subid IS NULL
declare @t table (RawlineNumber int, Claimid int, SubId varchar(5), SeqNumber int)

insert @t values(1, 6000, 'A100', 1)
insert @t values(2, 6000, NULL, 2)
insert @t values(3, 6000, NULL, 3)
insert @t values(10, 6000, 'A200', 1)
insert @t values(11, 6000, NULL, 2)
insert @t values(25, 6000, 'A300', 1)
insert @t values(26, 6000, NULL, 2)
insert @t values(27, 6000, NULL, 3)

;with cte as
(
select Rawlinenumber, SeqNumber, SubId
from @t where SubId is not null and SeqNumber = 1
union all
select t.Rawlinenumber, t.SeqNumber, c.SubId
from cte c
join
@t t
on c.Rawlinenumber + 1 = t.Rawlinenumber
and c.SeqNumber + 1 = t.SeqNumber
where t.SubId is null and t.SeqNumber > 1
)
update t 
set SubId = c.SubId
from @t t join cte c 
on c.Rawlinenumber = t.Rawlinenumber
where t.SeqNumber > 1

select * from @t

+1-很好。我从来没有想过在这样的事情上使用交叉申请。我只是一个新的交叉申请者。你能告诉我你在这里用什么字段作为身份证吗。我想他的意思是RawlineNumber@Quassnoi. 谢谢。它起作用了。同时,我还了解了CROSS APPLY的功能-卡西诺-不,当然不是。它看起来不错,但与问题的描述相比,它非常简单。我确实相信人们对分数非常慷慨。谢谢你。在我的场景中,seq和RawLineNumber不会有差距。所以没有测试这些场景…所以Quassnoi的解决方案工作得很好。