使用 CTE 代替光标

发布于 2024-11-25 06:11:54 字数 720 浏览 3 评论 0原文

我有以下表结构。

我只想将 SubId 更新为 null 且 RawLineNumber 升序 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

我要更新 RawLineNumber 2 和 3 的 SubId 与 A100,
SubId of RawLineNumber 11,A200,
A300 的 RawLineNumber 26 和 27 的 SubId

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

I have the following table structure.

I just want to update SubId to all the rows where it is null and where the RawLineNumber is ascending by 1 and also the SeqNumber ascending by 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

I want to update
SubId of RawLineNumber 2 and 3 with A100,
SubId of RawLineNumber 11 with A200,
SubId of RawLineNumber 26 and 27 with A300.

I have a cursor which does the job but can I have a CTE to take care of it ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

强辩 2024-12-02 06:11:54
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
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
善良天后 2024-12-02 06:11:54

由于需要一种隐性解决方案,我决定编写一个。它还适用于 Seqnumbers 和 RawlineNumber 中的间隙

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

Since a recusive solution was requested, I decided to write one. Also it works for gaps in Seqnumbers and RawlineNumber

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
沉溺在你眼里的海 2024-12-02 06:11:54

一个不那么简单的 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 的最后一行,
外部子选择为我们提供了该行的 SubID(使用窗口函数会更有效,但由于您没有提到特定的 RDBMS,所以我坚持这一点:-))

A not-so simple SQL script should achieve what you want:

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;

The inner subselect (T3) gives us the last row having seqnumber = 1 before the current line,
the outer subselect gives us the SubID for this row (using windowing functions would be more efficient, but since you didn't mention a specific RDBMS, I stick with this :-) )

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文