आइए विभिन्न विशेषताओं पर जंजीर डुप्लिकेट के साथ कुछ दिलचस्प डेटा प्राप्त करें:
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