sql >> Database teknologi >  >> RDS >> Sqlserver

SQL Server:Fletning af flere rækker af data til en enkelt række

Dette vil virke, men da der ikke er nogen kolonne med identitet eller dato - er der ingen måde at finde ud af, hvilken opdateringsrække der er nyere. Så hvis der er flere opdateringer på samme kolonne, tager jeg bare den første alfabetisk/numerisk (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 DEMO

Hvis identitetskolonnen kan tilføjes, kan vi bare omskrive CTE-delen for at gøre den mere nøjagtig.

EDIT:

Hvis vi har en identitetskolonne, og CTE omskrives til at blive rekursiv, kan faktisk hele den anden del af forespørgslen droppes.

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
 

SQLFiddle DEMO



  1. Få lagrede procedureparametre med enten C# eller SQL?

  2. Left Outer Join returnerer ikke alle poster fra den primære tabel

  3. Fjern de sidste to tegn i en kolonne i MySQL

  4. Sådan installeres SQL Server på Ubuntu 18.04