Điều này sẽ hoạt động, nhưng vì không có cột nhận dạng hoặc ngày giờ - không có cách nào để tìm hàng cập nhật nào mới hơn. Vì vậy, nếu có nhiều cập nhật hơn trên cùng một cột, tôi chỉ lấy chữ cái / số đầu tiên theo thứ tự bảng chữ cái / số (MIN).
WITH CTE AS
(
SELECT ID, REF, MIN(Title) Title, MIN(Surname) Surname, MIN(Forename) Forename, MIN(DOB) DOB, MIN(Add1) Add1, MIN(Postcode) Postcode
FROM Table1
GROUP BY id, REF
)
SELECT
d.REF
, d.ID
, COALESCE(T.Title, d.TItle) AS Title
, COALESCE(T.Surname, d.Surname) AS Surname
, COALESCE(T.Forename, d.Forename) AS Forename
, COALESCE(T.DOB, d.DOB) AS DOB
, COALESCE(T.Add1, d.Add1) AS Add1
, COALESCE(T.Postcode, d.Postcode) AS Postcode
FROM CTE d
INNER JOIN CTE t ON d.ID = t.ID AND d.REF = 'D' AND t.REF = 't'
Nếu cột nhận dạng có thể được thêm vào, chúng tôi chỉ có thể viết lại phần CTE để làm cho nó chính xác hơn.
CHỈNH SỬA:
Nếu chúng ta có cột nhận dạng và CTE được viết lại để trở thành đệ quy, thì thực sự toàn bộ phần khác của truy vấn có thể bị loại bỏ.
WITH CTE_RN AS
(
--Assigning row_Numbers based on identity - it has to be done since identity can always have gaps which would break the recursion
SELECT *, ROW_NUMBER() OVER (PARTITION BY ID ORDER BY IDNT DESC) RN FROM dbo.Table2
)
,RCTE AS
(
SELECT ID ,
Title ,
Surname ,
Forename ,
DOB ,
Add1 ,
Postcode ,
RN FROM CTE_RN WHERE RN = 1 -- taking the last row for each ID
UNION ALL
SELECT r.ID,
COALESCE(r.TItle,p.TItle), --Coalesce will hold prev value if exist or use next one
COALESCE(r.Surname,p.Surname),
COALESCE(r.Forename,p.Forename),
COALESCE(r.DOB,p.DOB),
COALESCE(r.Add1,p.Add1),
COALESCE(r.Postcode,p.Postcode),
p.RN
FROM RCTE r
INNER JOIN CTE_RN p ON r.ID = p.ID AND r.RN + 1 = p.RN --joining the previous row for each id
)
,CTE_Group AS
(
--rcte now holds both merged and unmerged rows, merged is max(rn)
SELECT ID, MAX(RN) RN FROM RCTE
GROUP BY ID
)
SELECT r.* FROM RCTE r
INNER JOIN CTE_Group g ON r.ID = g.ID AND r.RN = g.RN