Sqlserver
 sql >> डेटाबेस >  >> RDS >> Sqlserver

SQL सर्वर:डेटा की कई पंक्तियों को एक पंक्ति में मर्ज करना

यह काम करेगा, लेकिन चूंकि कोई पहचान या डेटाटाइम कॉलम नहीं है - यह पता लगाने का कोई तरीका नहीं है कि कौन सी अद्यतन पंक्ति नई है। इसलिए यदि एक ही कॉलम पर और अपडेट हैं, तो मैं केवल पहले अक्षर/संख्यात्मक (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

यदि पहचान कॉलम जोड़ा जा सकता है, तो हम इसे और अधिक सटीक बनाने के लिए सीटीई भाग को फिर से लिख सकते हैं।

संपादित करें:

यदि हमारे पास पहचान कॉलम है, और सीटीई को पुनरावर्ती बनने के लिए फिर से लिखा जाता है, तो वास्तव में क्वेरी के पूरे अन्य भाग को छोड़ा जा सकता है।

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. एसक्यूएल सर्वर 2008 में छवि डेटाटाइप को वर्चर में कनवर्ट करें:

  2. SQL सर्वर में एक टेबल पर DML ट्रिगर का प्रकार लौटाएं

  3. एक पंक्ति में एकाधिक SQL पंक्तियों का चयन करें

  4. SQL सर्वर में डेटाबेस मेल को कॉन्फ़िगर करना

  5. SQL अद्यतन विदेशी भाषाओं (अरबी) के साथ काम नहीं करता