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

Oracle में प्राथमिक कुंजी वाली डुप्लिकेट पंक्तियों को खोजने के 11 तरीके

ओरेकल डेटाबेस में डुप्लिकेट पंक्तियों को वापस करने के लिए यहां ग्यारह विकल्प दिए गए हैं, जब उन पंक्तियों में प्राथमिक कुंजी या कोई अन्य विशिष्ट पहचानकर्ता कॉलम होता है और आप इसे अनदेखा करना चाहते हैं।

नमूना डेटा

हम अपने उदाहरणों के लिए निम्नलिखित डेटा का उपयोग करेंगे:

SELECT * FROM Dogs;

परिणाम:

<थ>अंतिम नाम
DOGID FIRSTNAME
1 छाल स्मिथ
2 छाल स्मिथ
3 वूफ़ जोन्स
4 रफ़ रॉबिन्सन
5 वाग जॉनसन
6 वाग जॉनसन
7 वाग जॉनसन

पहली दो पंक्तियाँ डुप्लिकेट हैं और अंतिम तीन पंक्तियाँ डुप्लिकेट हैं। डुप्लीकेट पंक्तियों में उनके प्राथमिक कुंजी/अद्वितीय आईडी कॉलम के अपवाद के साथ सभी स्तंभों में बिल्कुल समान मान होते हैं।

प्राथमिक कुंजी कॉलम यह सुनिश्चित करता है कि कोई डुप्लिकेट पंक्तियाँ नहीं हैं, जो कि RDBMS में अच्छा अभ्यास है, क्योंकि प्राथमिक कुंजियाँ डेटा अखंडता को लागू करने में मदद करती हैं। लेकिन तथ्य यह है कि प्राथमिक कुंजी में अद्वितीय मान होते हैं, इसका मतलब है कि डुप्लिकेट की खोज करते समय हमें उस कॉलम को अनदेखा करना होगा।

ऊपर हमारी तालिका में, प्राथमिक कुंजी कॉलम एक वृद्धिशील संख्या है, और इसका मान कोई अर्थ नहीं रखता है और यह महत्वपूर्ण नहीं है। इसलिए हम डुप्लिकेट की खोज करते समय उस कॉलम के डेटा को अनदेखा कर सकते हैं।

विकल्प 1

डुप्लीकेट वापस करने के लिए हमारा पहला विकल्प यहां दिया गया है:

SELECT 
    FirstName, 
    LastName, 
    COUNT(*) AS Count
FROM Dogs
GROUP BY FirstName, LastName
ORDER BY Count DESC;

परिणाम:

<थ>अंतिम नाम
FIRSTNAME COUNT
वाग जॉनसन 3
छाल स्मिथ 2
रफ रॉबिन्सन 1
वूफ़ जोन्स 1

यहां हमने GROUP BY . के साथ अपनी क्वेरी तैयार की है क्लॉज ताकि आउटपुट को संबंधित कॉलम द्वारा समूहीकृत किया जा सके। हमने COUNT() . का भी इस्तेमाल किया समान पंक्तियों की संख्या वापस करने के लिए कार्य। और हमने इसे अवरोही क्रम में गिनती के आधार पर आदेश दिया ताकि डुप्लीकेट पहले दिखाई दें।

परिणाम हमें बताता है कि वैग जॉनसन वाली तीन पंक्तियाँ और बार्क स्मिथ वाली दो पंक्तियाँ हैं। ये डुप्लीकेट हैं (या वैग जॉनसन के मामले में तीन प्रतियों में)। अन्य दो पंक्तियों में कोई डुप्लीकेट नहीं है।

विकल्प 2

हम HAVING . जोड़ सकते हैं आउटपुट से गैर-डुप्लिकेट को बाहर करने के लिए हमारे पिछले उदाहरण का खंड:

SELECT 
    FirstName, 
    LastName, 
    COUNT(*) AS Count
FROM Dogs
GROUP BY FirstName, LastName
HAVING COUNT(*) > 1
ORDER BY Count DESC;

परिणाम:

<थ>अंतिम नाम
FIRSTNAME COUNT
वाग जॉनसन 3
छाल स्मिथ 2

विकल्प 3

हम समवर्ती स्तंभों पर डुप्लीकेट की जांच भी कर सकते हैं। इस मामले में हम DISTINCT . का उपयोग करते हैं विशिष्ट मान प्राप्त करने के लिए कीवर्ड, फिर COUNT() . का उपयोग करें गिनती वापस करने के लिए कार्य करें:

SELECT
    DISTINCT FirstName || ' ' || LastName AS DogName,
    COUNT(*) AS Count
FROM Dogs
GROUP BY FirstName || ' ' || LastName
ORDER BY Count DESC;

परिणाम:

DOGNAME COUNT
वैग जॉनसन 3
बार्क स्मिथ 2
रफ रॉबिन्सन 1
वूफ जोन्स 1

विकल्प 4

Oracle की प्रत्येक पंक्ति में एक rowid होता है स्यूडोकॉलम जो पंक्ति का पता देता है। rowid तालिका में पंक्तियों के लिए एक अद्वितीय पहचानकर्ता है, और आमतौर पर इसका मान विशिष्ट रूप से डेटाबेस में एक पंक्ति की पहचान करता है (हालांकि यह ध्यान रखना महत्वपूर्ण है कि एक ही क्लस्टर में एक साथ संग्रहीत विभिन्न तालिकाओं में पंक्तियों में एक ही rowid हो सकता है। कोड> )।

वैसे भी, हम एक क्वेरी बना सकते हैं जो rowid . का उपयोग करती है अगर हम चाहते हैं:

SELECT * FROM Dogs
WHERE EXISTS (
  SELECT 1 FROM Dogs d2 
  WHERE Dogs.FirstName = d2.FirstName
  AND Dogs.LastName = d2.LastName
  AND Dogs.rowid > d2.rowid
);

परिणाम:

<थ>अंतिम नाम
DOGID FIRSTNAME
2 छाल स्मिथ
6 वाग जॉनसन
7 वाग जॉनसन

हम SELECT * . को बदल सकते हैं DELETE के साथ टेबल पर डी-डुपिंग ऑपरेशन करने के लिए।

ध्यान दें कि हम DogId . का उपयोग कर सकते थे rowid . के बजाय कॉलम (हमारी प्राथमिक कुंजी) अगर हम चाहते थे। उस ने कहा, rowid यदि आप किसी कारण से प्राथमिक कुंजी कॉलम का उपयोग नहीं कर सकते हैं, या तालिका में प्राथमिक कुंजी नहीं है, तो यह उपयोगी हो सकता है।

विकल्प 5

यहां एक और क्वेरी है जो rowid . का उपयोग करती है :

SELECT * FROM Dogs
WHERE rowid > (
  SELECT MIN(rowid) FROM Dogs d2  
  WHERE Dogs.FirstName = d2.FirstName
  AND Dogs.LastName = d2.LastName
);

परिणाम:

<थ>अंतिम नाम
DOGID FIRSTNAME
2 छाल स्मिथ
6 वाग जॉनसन
7 वाग जॉनसन

पिछले उदाहरण की तरह, हम SELECT * . को बदल सकते हैं DELETE के साथ डुप्लिकेट पंक्तियों को हटाने के लिए।

विकल्प 6

दो rowid यदि आपको अपनी क्वेरी में प्राथमिक कुंजी को पूरी तरह से अनदेखा करना चाहिए (या यदि आपके पास प्राथमिक कुंजी कॉलम बिल्कुल नहीं है) तो उपरोक्त विकल्प बहुत अच्छे हैं। हालांकि जैसा कि बताया गया है, अभी भी rowid . को बदलने का विकल्प है प्राथमिक कुंजी कॉलम के साथ - हमारे मामले में DogId कॉलम:

SELECT * FROM Dogs
WHERE EXISTS (
  SELECT 1 FROM Dogs d2 
  WHERE Dogs.FirstName = d2.FirstName
  AND Dogs.LastName = d2.LastName
  AND Dogs.DogId > d2.DogId
);

परिणाम:

<थ>अंतिम नाम
DOGID FIRSTNAME
2 छाल स्मिथ
6 वाग जॉनसन
7 वाग जॉनसन

Option 7

और यहां rowid के साथ अन्य क्वेरी है DogId . द्वारा प्रतिस्थापित किया गया कॉलम:

SELECT * FROM Dogs
WHERE DogId > (
  SELECT MIN(DogId) FROM Dogs d2  
  WHERE Dogs.FirstName = d2.FirstName
  AND Dogs.LastName = d2.LastName
);

परिणाम:

<थ>अंतिम नाम
DOGID FIRSTNAME
2 छाल स्मिथ
6 वाग जॉनसन
7 वाग जॉनसन

विकल्प 8

डुप्लीकेट खोजने का दूसरा तरीका ROW_NUMBER() . का उपयोग करना है विंडो फ़ंक्शन:

SELECT 
    DogId,
    FirstName,
    LastName,
    ROW_NUMBER() OVER ( 
        PARTITION BY FirstName, LastName 
        ORDER BY FirstName, LastName
        ) AS row_num
FROM Dogs;

परिणाम:

<थ>अंतिम नाम
DOGID FIRSTNAME ROW_NUM
1 छाल स्मिथ 1
2 छाल स्मिथ 2
4 रफ़ रॉबिन्सन 1
7 वाग जॉनसन 1
5 वाग जॉनसन 2
6 वाग जॉनसन 3
3 वूफ़ जोन्स 1

PARTITION का उपयोग करना क्लॉज के परिणामस्वरूप एक नया कॉलम जोड़ा जाता है, जिसमें एक पंक्ति संख्या होती है जो हर बार डुप्लिकेट होने पर बढ़ती है, लेकिन एक अद्वितीय पंक्ति होने पर फिर से रीसेट हो जाती है।

इस मामले में हम परिणामों को समूहीकृत नहीं करते हैं, जिसका अर्थ है कि हम प्रत्येक डुप्लिकेट पंक्ति को उसके विशिष्ट पहचानकर्ता कॉलम सहित देख सकते हैं।

विकल्प 9

हम पिछले उदाहरण का उपयोग एक बड़ी क्वेरी में एक सामान्य तालिका अभिव्यक्ति के रूप में भी कर सकते हैं:

WITH cte AS 
    (
        SELECT 
            DogId,
            FirstName,
            LastName,
            ROW_NUMBER() OVER ( 
                PARTITION BY FirstName, LastName 
                ORDER BY FirstName, LastName
                ) AS row_num
        FROM Dogs
    )
SELECT * FROM cte WHERE row_num <> 1;

परिणाम:

<थ>अंतिम नाम
DOGID FIRSTNAME ROW_NUM
2 छाल स्मिथ 2
5 वाग जॉनसन 2
6 वाग जॉनसन 3

वह क्वेरी आउटपुट से गैर-डुप्लिकेट को बाहर करती है, और यह आउटपुट से प्रत्येक डुप्लिकेट की एक पंक्ति को बाहर करती है।

विकल्प 10

पिछले उदाहरण के समान आउटपुट प्राप्त करने का एक और तरीका यहां दिया गया है:

SELECT * FROM Dogs 
WHERE DogId IN (
    SELECT DogId FROM Dogs 
    MINUS SELECT MIN(DogId) FROM Dogs 
    GROUP BY FirstName, LastName
    );

परिणाम:

<थ>अंतिम नाम
DOGID FIRSTNAME
2 छाल स्मिथ
6 वाग जॉनसन
7 वाग जॉनसन

यह उदाहरण Oracle के MINUS . का उपयोग करता है ऑपरेटर, जो केवल पहली क्वेरी द्वारा लौटाई गई अनूठी पंक्तियों को लौटाता है, लेकिन दूसरे द्वारा नहीं।

MINUS ऑपरेटर EXCEPT . के समान है अन्य DBMS में ऑपरेटर, जैसे SQL Server, MariaDB, PostgreSQL, और SQLite।

विकल्प 11

हमारी तालिका से डुप्लीकेट चुनने का एक और विकल्प यहां दिया गया है:

SELECT * 
FROM Dogs d1, Dogs d2 
WHERE d1.FirstName = d2.FirstName 
AND d1.LastName = d2.LastName
AND d1.DogId <> d2.DogId 
AND d1.DogId = (
    SELECT MAX(DogId) 
    FROM Dogs d3 
    WHERE d3.FirstName = d1.FirstName 
    AND d3.LastName = d1.LastName
);

परिणाम:

<थ>अंतिम नाम <थ>अंतिम नाम
DOGID FIRSTNAME DOGID FIRSTNAME
2 छाल स्मिथ 1 छाल स्मिथ
7 वाग जॉनसन 5 वाग जॉनसन
7 वाग जॉनसन 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. सी #:ऑब्जेक्ट को डीबीएनयूएल से अन्य प्रकारों में नहीं डाला जा सकता है

  2. Oracle डेटाटाइप:क्या मुझे VARCHAR2 या CHAR . का उपयोग करना चाहिए?

  3. ऑरैकल क्वेरी में इनपुट के रूप में स्ट्रिंग मान 1,2 पास करने में असमर्थ

  4. Oracle तालिकाओं में बड़े आकार के डेटा को कैसे सम्मिलित/अपडेट करें?

  5. ओरेकल ईबीएस पासवर्ड समाप्ति/नीति/सेटिंग्स पर उपयोगी प्रश्न