sql >> データベース >  >> RDS >> Sqlserver

SQL Server :複数行のデータを 1 つの行にマージする

    これは機能しますが、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'
    

    SQLFiddle デモ

    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
    

    SQLFiddle デモ



    1. PDOSSSL接続でエラーが発生しました

    2. Android-データはスピナーに割り当てられますが、選択するとスピナーに値が表示されません

    3. Laravel:SQLSTATE[HY000][2054]サーバーがクライアントに不明な認証方法を要求しました

    4. OUTPUT句を使用してINSERTEDにない値を挿入する