После CTE
возвращает заданный вывод для заданных вами входов. Вы можете использовать эти результаты в качестве отправной точки для вставки записей в другую таблицу.
Суть этого
- Использовать рекурсив
CTE
, начиная со всех строк, где rn=1
.
- В рекурсивной части выберите
Data1-3
из рекурсивной части, если она доступна, в противном случае сохраните существующее значение (COALESCE
). Результатом CTE
теперь являются ваши окончательные значения + начальные значения, где rn=1
- Добавьте
ROW_NUMBER
для каждого userID
, но ORDER DESC
для существующего rn
. Это гарантирует, что последние значения получат номер 1.
- Наконец, выберите все с помощью rownumber 1 и добавьте еще одно rownumber согласно вашим окончательным результатам.
Оператор SQL
;WITH q AS (
SELECT rn
, UserID
, Data1
, Data2
, Data3
FROM Inherited
WHERE rn = 1
UNION ALL
SELECT i.rn
, i.UserID
, COALESCE(i.Data1, q.Data1)
, COALESCE(i.Data2, q.Data2)
, COALESCE(i.Data3, q.Data3)
FROM q
INNER JOIN Inherited i ON i.rn = q.rn+1 AND i.userID = q.userID
)
SELECT rn = ROW_NUMBER() OVER (ORDER BY userID)
, *
FROM (
SELECT UserID
, Data1
, Data2
, Data3
, rn = ROW_NUMBER() OVER (PARTITION BY UserID ORDER BY rn DESC)
FROM q
) t
WHERE rn = 1
Тестовый скрипт
;WITH Inherited (rowID, rn, userID, Data1, Data2, Data3) AS (
SELECT * FROM (VALUES
(1, 1, 1, 'A', null, '123')
, (2, 2, 1, 'B', '111', null)
, (3, 1, 2, 'C', '222', '333')
, (4, 2, 2, 'D', null, null)
, (5, 3, 2, 'E', '111', null)
, (6, 1, 3, 'F', '333', '222')
) a (b, c, d, e, f, g)
)
, q AS (
SELECT rn
, UserID
, Data1
, Data2
, Data3
FROM Inherited
WHERE rn = 1
UNION ALL
SELECT i.rn
, i.UserID
, COALESCE(i.Data1, q.Data1)
, COALESCE(i.Data2, q.Data2)
, COALESCE(i.Data3, q.Data3)
FROM q
INNER JOIN Inherited i ON i.rn = q.rn+1 AND i.userID = q.userID
)
SELECT rn = ROW_NUMBER() OVER (ORDER BY userID)
, *
FROM (
SELECT UserID
, Data1
, Data2
, Data3
, rn = ROW_NUMBER() OVER (PARTITION BY UserID ORDER BY rn DESC)
FROM q
) t
WHERE rn = 1