Sqlserver
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Sqlserver

Máy chủ SQL:Hợp nhất một số dòng dữ liệu thành một hàng duy nhất

Đ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'

SQLFiddle DEMO

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

SQLFiddle DEMO



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Tìm hàng tiếp theo trong truy vấn SQL và chỉ xóa nó nếu hàng trước đó khớp

  2. Làm cách nào để chạy một thủ tục được lưu trữ hàng ngày trong SQL Server Express Edition?

  3. Lỗi sql tên cột không hợp lệ

  4. Tính toán các ngày để loại trừ các ngày cuối tuần (Thứ Hai đến Thứ Sáu) trong SQL Server

  5. Làm cách nào để kết nối với cơ sở dữ liệu SQL Server trong CodeIgniter?