sql - तालिका में तार्किक रूप से डुप्लिकेट पंक्तियों की पहचान करना




sql-server datatables duplicates (4)

/*
CREATE  TABLE myTest
    (ID INT,
    Player1 VARCHAR(50),
    Player2 VARCHAR(50),
    Player3 VARCHAR(50));
GO

INSERT INTO myTest
VALUES
    (101, 'Tom', 'Dick', 'Harry'),
    (102, 'Jack', 'Martin', 'Anna'),
    (103, 'Harry', 'Tom', 'Dick');
GO
*/
WITH
    Players AS (
        SELECT
            ID,
            Player1 AS Player
        FROM
            myTest
        UNION ALL
        SELECT
            ID,
            Player2 AS Player
        FROM
            myTest
        UNION ALL
        SELECT
            ID,
            Player3 AS Player
        FROM
            myTest),
    PlayersSorted AS (
        SELECT
            *,
            ROW_NUMBER() OVER (PARTITION BY ID ORDER BY Player) AS RowNo
        FROM
            Players)
SELECT DISTINCT
    a.ID
FROM
    PlayersSorted a
JOIN
    PlayersSorted b
        ON a.ID <> b.ID
        AND a.Player = b.Player
        AND a.RowNo = b.RowNo;

यहां मेरा इनपुट टेबल है

   ID   | Player1 | Player2 | Player3
  ===================================
   101  |   Tom   |  Dick   | Harry
   102  |  Jack   | Martin  | Anna
   103  |  Harry  |  Tom    | Dick

यहां हम देखते हैं, आईडी 101 और 103 के लिए, खिलाड़ी अनिवार्य रूप से समान हैं, यद्यपि भिन्न क्रम में। इसलिए उन्हें डुप्लिकेट पंक्तियों के रूप में माना जाना चाहिए।

क्वेरी लिखकर, मैं किसी भी तरह डुप्लिकेट पंक्तियों की पहचान कैसे करूं ?? कुछ ऐसा है जो "आईडी 101 और आईडी 103 डुप्लिकेट हैं" देता है ??


यह काम करना चाहिए:

WITH Src AS
(
    SELECT * FROM (VALUES
    (101, 'Tom', 'Dick', 'Harry'),
    (102, 'Jack', 'Martin', 'Anna'),
    (103, 'Harry', 'Tom', 'Dick'),
    (104, 'Dick', 'Tom', 'Harry'),
    (105, 'Anna', 'Martin', 'Jack'),
    (106, 'Anna', 'Martin', 'Joe')
    ) T(ID, Player1, Player2, Player3)
), Numbered AS
(
    SELECT ID, Name, ROW_NUMBER() OVER (PARTITION BY ID ORDER BY Name) N
    FROM
    (
        SELECT ID,
            CONVERT(nvarchar(MAX), Player1) Player1,
            CONVERT(nvarchar(MAX), Player2) Player2,
            CONVERT(nvarchar(MAX), Player3) Player3
        FROM Src
    ) T1
    UNPIVOT
    (Name FOR Player IN (Player1, Player2, Player3)) PV
), Grouped AS
(
    SELECT N1.ID, N2.ID DuplicateID
    FROM Numbered N1
    CROSS JOIN Numbered N2
    GROUP BY N1.ID,N2.ID
    HAVING SUM(CASE WHEN N1.N=N2.N AND N1.ID!=N2.ID AND N1.Name=N2.Name THEN 1 END)=MAX(N1.N)
)
SELECT *
FROM Grouped
WHERE ID<DuplicateID

आपको प्रत्येक आईडी के लिए 3 मानों से न्यूनतम प्राप्त करने की आवश्यकता है

player1+player2+player3
player2+player3+player1
player3+player1+player2

न्यूनतम मूल्य प्राप्त करने के लिए चयन करें

Select sub.id, min(sub.name)
FROM (
    select
         t.id,
         CASE 
            WHEN rows.row=1 THEN t.player1+t.player2+t.player3
            WHEN rows.row=2 THEN t.player2+t.player3+t.player1
            WHEN rows.row=3 THEN t.player3+t.player1+t.player2
         END as name
    from t,
         (select 1 as row
          union
          select 2 as row
          union
          select 3 as row) rows) sub
GROUP by sub.id

तो आपके पास इस तरह की मेज है

ID concat_names
1 DickHarryTom
2 AnnaJackMartin
3 DickHarryTom

और डुप्लिकेट ढूंढने के लिए आप कंसैट_नामों की तुलना कर सकते हैं


एक्सएमएल का उपयोग करने से मुझे पंक्तियों को अल्पविराम से अलग करने में मदद मिली। अतिरिक्त अल्पविराम के लिए हम SQL सर्वर के प्रतिस्थापन फ़ंक्शन का उपयोग कर सकते हैं। अल्पविराम जोड़ने के बजाय, एएस 'डेटा ()' का उपयोग रिक्त स्थान के साथ पंक्तियों को जोड़ देगा, जिसे बाद में नीचे लिखा गया वाक्यविन्यास के रूप में अल्पविरामों के साथ प्रतिस्थापित किया जा सकता है।

REPLACE(
        (select FName AS 'data()'  from NameList  for xml path(''))
         , ' ', ', ') 




sql sql-server datatables duplicates