我想要做的是合并几行数据,以便在Transact-SQL或SSIS中将其显示为单行。因此,例如:
制作:
REF ID Title Surname Forename DOB Add1 Postcode ------------------------------------------------------------------------------------------ D 10 MR KINGSTON NULL 15/07/1975 3 WATER SQUARE NULL T 10 NULL NULL BOB NULL NULL NULL T 10 MRS NULL NULL NULL NULL TW13 7DT
到这个:
REF ID Title Surname Forename DOB Add1 Postcode ---------------------------------------------------------------------------------- D 10 MRS KINGSTON BOB 15/07/1975 3 WATER SQUARE TW13 7DT
因此,我所做的就是将值合并在一起,而忽略了null值。(D =数据; T =更新)
任何建议将是最欢迎的。
谢谢。
这将起作用,但是由于没有标识或日期时间列-无法找到哪个更新行是较新的。因此,如果同一列上有更多更新,那么我只需按字母/数字(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'
SQLFiddle演示
如果可以添加标识列,我们可以重写CTE部分以使其更准确。
编辑:
如果我们有标识列,并且将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