これは機能しますが、ID または日時列がないため、どの更新行が新しいかを見つける方法がありません。したがって、同じ列にさらに更新がある場合は、アルファベット順または数字順 (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'
ID 列を追加できる場合は、CTE 部分を書き直してより正確にすることができます。
編集:
ID 列があり、CTE が再帰的に書き換えられると、実際にはクエリの他の部分全体が削除される可能性があります。
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