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

एसक्यूएल कई फ़ील्ड के साथ डुप्लिकेट ढूंढें (कोई अद्वितीय आईडी नहीं) चारों ओर काम करें

आइए विभिन्न विशेषताओं पर जंजीर डुप्लिकेट के साथ कुछ दिलचस्प डेटा प्राप्त करें:

CREATE TABLE data ( ID, A, B, C ) AS
  SELECT 1, 1, 1, 1 FROM DUAL UNION ALL -- Related to #2 on column A
  SELECT 2, 1, 2, 2 FROM DUAL UNION ALL -- Related to #1 on column A, #3 on B & C, #5 on C
  SELECT 3, 2, 2, 2 FROM DUAL UNION ALL -- Related to #2 on columns B & C, #5 on C
  SELECT 4, 3, 3, 3 FROM DUAL UNION ALL -- Related to #5 on column A
  SELECT 5, 3, 4, 2 FROM DUAL UNION ALL -- Related to #2 and #3 on column C, #4 on A
  SELECT 6, 5, 5, 5 FROM DUAL;          -- Unrelated

अब, हम विश्लेषणात्मक कार्यों (बिना किसी जुड़ाव के) का उपयोग करके कुछ संबंध प्राप्त कर सकते हैं:

SELECT d.*,
       LEAST(
         FIRST_VALUE( id ) OVER ( PARTITION BY a ORDER BY id ),
         FIRST_VALUE( id ) OVER ( PARTITION BY b ORDER BY id ),
         FIRST_VALUE( id ) OVER ( PARTITION BY c ORDER BY id )
       ) AS duplicate_of
FROM   data d;

जो देता है:

ID A B C DUPLICATE_OF
-- - - - ------------
 1 1 1 1            1
 2 1 2 2            1
 3 2 2 2            2
 4 3 3 3            4
 5 3 4 2            2
 6 5 5 5            6

लेकिन इसका मतलब यह नहीं है कि #4 #5 से संबंधित है जो #2 से संबंधित है और फिर # 1...

यह एक पदानुक्रमित क्वेरी के साथ पाया जा सकता है:

SELECT id, a, b, c,
       CONNECT_BY_ROOT( id ) AS duplicate_of
FROM   data
CONNECT BY NOCYCLE ( PRIOR a = a OR PRIOR b = b OR PRIOR c = c );

लेकिन यह कई, कई डुप्लिकेट पंक्तियां देगा (क्योंकि यह नहीं जानता कि पदानुक्रम कहां से शुरू करना है, इसलिए प्रत्येक पंक्ति को रूट के रूप में चुना जाएगा) - इसके बजाय आप पदानुक्रमित क्वेरी को प्रारंभिक बिंदु देने के लिए पहली क्वेरी का उपयोग कर सकते हैं जब ID और DUPLICATE_OF मान समान हैं:

SELECT id, a, b, c,
       CONNECT_BY_ROOT( id ) AS duplicate_of
FROM   (
  SELECT d.*,
         LEAST(
           FIRST_VALUE( id ) OVER ( PARTITION BY a ORDER BY id ),
           FIRST_VALUE( id ) OVER ( PARTITION BY b ORDER BY id ),
           FIRST_VALUE( id ) OVER ( PARTITION BY c ORDER BY id )
         ) AS duplicate_of
  FROM   data d
)
START WITH id = duplicate_of
CONNECT BY NOCYCLE ( PRIOR a = a OR PRIOR b = b OR PRIOR c = c );

जो देता है:

ID A B C DUPLICATE_OF
-- - - - ------------
 1 1 1 1            1
 2 1 2 2            1
 3 2 2 2            1
 4 3 3 3            1
 5 3 4 2            1
 1 1 1 1            4
 2 1 2 2            4
 3 2 2 2            4
 4 3 3 3            4
 5 3 4 2            4
 6 5 5 5            6

खोज में स्थानीय मिनीमा के कारण अभी भी कुछ पंक्तियों की नकल की जाती है जो #4 ... होती है जिसे एक साधारण GROUP BY से हटाया जा सकता है :

SELECT id, a, b, c,
       MIN( duplicate_of ) AS duplicate_of
FROM   (
  SELECT id, a, b, c,
         CONNECT_BY_ROOT( id ) AS duplicate_of
  FROM   (
    SELECT d.*,
           LEAST(
             FIRST_VALUE( id ) OVER ( PARTITION BY a ORDER BY id ),
             FIRST_VALUE( id ) OVER ( PARTITION BY b ORDER BY id ),
             FIRST_VALUE( id ) OVER ( PARTITION BY c ORDER BY id )
           ) AS duplicate_of
    FROM   data d
  )
  START WITH id = duplicate_of
  CONNECT BY NOCYCLE ( PRIOR a = a OR PRIOR b = b OR PRIOR c = c )
)
GROUP BY id, a, b, c;

जो आउटपुट देता है:

ID A B C DUPLICATE_OF
-- - - - ------------
 1 1 1 1            1
 2 1 2 2            1
 3 2 2 2            1
 4 3 3 3            1
 5 3 4 2            1
 6 5 5 5            6


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Oracle समवर्ती प्रबंधक

  2. Oracle समय क्षेत्र रूपांतरण (from_tz का उपयोग करके)

  3. ORACLE/ASP.NET:ORA-2020 - बहुत अधिक डेटाबेस लिंक... इसका क्या कारण है?

  4. क्या पीएल/एसक्यूएल कोड में DBMS_STANDARD पैकेज की प्रक्रियाओं और/या कार्यों का उपयोग किया जाना चाहिए?

  5. SqlPlus क्वेरी समस्या (पैकेज युक्ति और मुख्य भाग)