Sql server - избегайте курсора во время последовательного обновления
Как я могу избежать использования курсора для реализации следующего? Я читал, что это можно сделать с помощью CTE, но я не получил его работы с тем же результатом.
В этом примере я использую две таблицы: первая-это таблица держателей, содержащая список людей, и таблица переводов, где каждая передача указывает на изменение в конкретной записи первой таблицы.
Ниже вы можете увидеть код, который приносит правильные результаты:
create table #holders(Person VARCHAR(50), Kind VARCHAR(50), Pctg FLOAT) create table #transfers(Person_FROM VARCHAR(50), Person_To VARCHAR(50), Kind VARCHAR(50), Pctg_New FLOAT, Eff_Date DATE) insert into #holders select 'Person One', 'Kind 1', 50 union all select 'Person Two', 'Kind 1', 50 union all select 'Person Three', 'Kind 1', NULL union all select 'Person Four', 'Kind 1', NULL union all select 'Person One', 'Kind 2', 100 insert into #transfers select 'Person One', 'Person A', 'Kind 1', 70, '2019-12-31' union all select 'Person Two', 'Person B', 'Kind 1', 30, '2020-01-01' union all select 'Person A', 'Person A1', 'Kind 1', 70, '2020-01-02' union all select 'Person A', 'Person A2', 'Kind 1', 70, '2020-01-03' union all --Should Avoided select 'Person A2', 'Person A3', 'Kind 1', 70, '2020-01-04' union all --Should Avoided select 'Person A1', 'Person A4', 'Kind 1', 70, '2020-01-05' declare @Person_FROM varchar(50), @Person_To varchar(50), @Kind varchar(50), @Pctg_New float declare cur cursor for select Person_FROM, Person_To, Kind, Pctg_New from #transfers order by Eff_Date open cur fetch next from cur into @Person_FROM, @Person_To, @Kind, @Pctg_New while @@FETCH_STATUS = 0 begin update #holders set Person = @Person_To, Pctg = @Pctg_New where Person = @Person_FROM AND Kind = @Kind fetch next from cur into @Person_FROM, @Person_To, @Kind, @Pctg_New end close cur deallocate cur SELECT * FROM #holders drop table #holders drop table #transfers
Результаты должны быть именно такими:
https://i.stack.imgur.com/D552U.png
Я думаю, что ключ заключается в том, что необходимо сериализованное обновление (порядок по Eff_Date) и какое-то рекурсивное (первая строка должна обновляться 3 раза, используя этот поток: "человек один" --"человек а" --"человек А1" --"человек А4").
Любая помощь приветствуется! Заранее спасибо
Что я уже пробовал:
Я попытался решить эту проблему с помощью CTE и cross join, но безуспешно
ZurdoDev
Если вам все еще нужен цикл, но вы не хотите использовать курсор, вы всегда можете использовать цикл while.