SQL Server 2012,根据下一条记录更新记录
SQL Server 2012, update record based on next record
我正在努力寻找基于先前值的 更新(不仅仅是 select)SQL table 记录的解决方案。我可以让脚本用 LAG() 函数填充紧接的后续记录,但是当我在一行中有相同的值时(比如下面的 'CC'),我无法用下一个值填充它与当前值不同。
如果能够添加 CASE/WHEN 条件以便仅评估具有相同 BaseID 的值,这也会有所帮助。任何帮助将不胜感激。
这是我想要的结果:
BaseID Value Date NextValue
1 AA 2017-10-01 BB
1 BB 2017-10-02 CC
1 CC 2017-10-03 DD
1 CC 2017-10-03 DD
1 CC 2017-10-03 DD
1 DD 2017-10-04 NULL
2 EE 2017-10-01 FF
2 FF 2017-10-02 GG
2 GG 2017-10-03 NULL
获取不同的 baseid、值、日期组合并使用 lead
获取 cte 中的下一个值并将其用于 update
。
with cte as (select t1.baseid,t1.value,t1.nextvalue,t2.nxt_value
from tbl t1
left join (select t.*,lead(value) over(partition by baseid order by datecol) as nxt_value
from (select distinct baseid,datecol,value from tbl) t
) t2
on t1.baseid=t2.baseid and t1.datecol=t2.datecol and t1.value=t2.value
)
update cte set nextvalue=nxt_value
这假定给定的 baseid、日期组合不能有多个值。
这是一个使用 DENSE_RANK 作为另一个选项的工作示例。
declare @Something table
(
BaseID int
, MyValue char(2)
, MyDate date
, NextValue char(2)
)
insert @Something
(
BaseID
, MyValue
, MyDate
) VALUES
(1, 'AA', '2017-10-01')
, (1, 'BB', '2017-10-02')
, (1, 'CC', '2017-10-03')
, (1, 'CC', '2017-10-03')
, (1, 'CC', '2017-10-03')
, (1, 'DD', '2017-10-04')
, (2, 'EE', '2017-10-01')
, (2, 'FF', '2017-10-02')
, (2, 'GG', '2017-10-03')
;
with SortedResults as
(
select *
, DENSE_RANK() over(partition by BaseID order by BaseID, MyDate ) as MyRank
from @Something
)
update sr set NextValue = sr2.MyValue
from SortedResults sr
join SortedResults sr2 on sr2.MyRank - 1 = sr.MyRank and sr.BaseID = sr2.BaseID
select *
from @Something
我正在努力寻找基于先前值的 更新(不仅仅是 select)SQL table 记录的解决方案。我可以让脚本用 LAG() 函数填充紧接的后续记录,但是当我在一行中有相同的值时(比如下面的 'CC'),我无法用下一个值填充它与当前值不同。
如果能够添加 CASE/WHEN 条件以便仅评估具有相同 BaseID 的值,这也会有所帮助。任何帮助将不胜感激。
这是我想要的结果:
BaseID Value Date NextValue
1 AA 2017-10-01 BB
1 BB 2017-10-02 CC
1 CC 2017-10-03 DD
1 CC 2017-10-03 DD
1 CC 2017-10-03 DD
1 DD 2017-10-04 NULL
2 EE 2017-10-01 FF
2 FF 2017-10-02 GG
2 GG 2017-10-03 NULL
获取不同的 baseid、值、日期组合并使用 lead
获取 cte 中的下一个值并将其用于 update
。
with cte as (select t1.baseid,t1.value,t1.nextvalue,t2.nxt_value
from tbl t1
left join (select t.*,lead(value) over(partition by baseid order by datecol) as nxt_value
from (select distinct baseid,datecol,value from tbl) t
) t2
on t1.baseid=t2.baseid and t1.datecol=t2.datecol and t1.value=t2.value
)
update cte set nextvalue=nxt_value
这假定给定的 baseid、日期组合不能有多个值。
这是一个使用 DENSE_RANK 作为另一个选项的工作示例。
declare @Something table
(
BaseID int
, MyValue char(2)
, MyDate date
, NextValue char(2)
)
insert @Something
(
BaseID
, MyValue
, MyDate
) VALUES
(1, 'AA', '2017-10-01')
, (1, 'BB', '2017-10-02')
, (1, 'CC', '2017-10-03')
, (1, 'CC', '2017-10-03')
, (1, 'CC', '2017-10-03')
, (1, 'DD', '2017-10-04')
, (2, 'EE', '2017-10-01')
, (2, 'FF', '2017-10-02')
, (2, 'GG', '2017-10-03')
;
with SortedResults as
(
select *
, DENSE_RANK() over(partition by BaseID order by BaseID, MyDate ) as MyRank
from @Something
)
update sr set NextValue = sr2.MyValue
from SortedResults sr
join SortedResults sr2 on sr2.MyRank - 1 = sr.MyRank and sr.BaseID = sr2.BaseID
select *
from @Something