CTE рекурсивно обновляет значения полей, пока не останется никакого значения по умолчанию
Я пытаюсь написать рекурсию, которая обновляет значения поля, пока не останется значение по умолчанию '0'.
Отправной точкой является эта таблица:
USE [Test]
DROP TABLE IF EXISTS [Test].[dbo].[T0]
CREATE TABLE [Test].[dbo].[T0] (
ID1 nvarchar(50),
ID2 nvarchar(50),
Score decimal(18,0),
tag int
);
INSERT INTO [Test].[dbo].[T0] (ID1, ID2, Score, tag)
VALUES ('A1', 'B1', 100.0, 0),
('A1', 'B2', 90, 0),
('A2', 'B1', 80, 0),
('A2', 'B3', 70, 0),
('A3', 'B4', 85, 0),
('A4', 'B4', 75, 0),
('A5', 'B5', 85, 0),
('A5', 'B6', 75, 0);
Задача для всех строк с [tag] = 0 состоит в том, чтобы:
обновить значение поля [tag] до '1' в строке с наибольшим количеством очков,
обновите значение поля [tag] до '2', чтобы строки имели тот же [ID1] или [ID2], что и строка с наибольшим количеством очков.
Рекурсия должна продолжаться до тех пор, пока не останется больше строк со значением '0'.
Желаемый результат выглядит так:
ID1 ID2 Score tag
A1 B1 100 1
A1 B2 90 2
A2 B1 80 2
A2 B3 70 1
A3 B4 85 1
A4 B4 75 2
A5 B5 85 1
A5 B6 75 2
Я написал следующий CTE, который не зацикливается. Я должен запустить его четыре раза, чтобы получить правильный выход.
WITH T1 AS
(
Select distinct [ID1], [ID2], [Score], [tag]
,Rank() over (order by [Score] desc, [ID1] desc, [ID2] desc) as [rk]
from [Test].[dbo].[T0]
where [tag] = 0
group by [ID1], [ID2], [Score], [tag]
)
,T2 AS
(
Select distinct [ID1], [ID2]
,[Score]
,[rk]
,case when rk = 1 then 1 else [tag] end as [tag]
from [T1]
)
,T3 AS
(
Select [ID1], [ID2], [Score], 0 as rk, case when rk <> 1 and ([Top_ID1] is not null or [Top_ID2] is not null) then 2 else [tag] end as [tag]
from
(Select [ID1], [ID2], [Score], rk, tag from [T2]) T3_1
left outer join
(Select [ID1] as [Top_ID1], [ID2] as [Top_ID2] from [T2] where rk = 1) T3_2
on T3_1.[ID1] = T3_2.[Top_ID1] or T3_1.[ID2] = T3_2.[Top_ID2]
)
,T4 AS
(
Select distinct [ID1], [ID2], [Score], [rk], [tag]
from [T3]
where [tag] = 0
union all
Select [ID1], [ID2], [Score], [rk], [tag]
from [T4]
where [tag] = 0
)
Update [Test].[dbo].[T0]
Set [tag] = [T4].[tag]
from [T4]
join [Test].[dbo].[T0] D on D.[ID1] = [T4].[ID1] and D.[ID2] = [T4].[ID2]
option ( MaxRecursion 0 );
Кто-нибудь знает, как изменить код для рекурсии на работу?
Спасибо за вашу помощь!