2012-07-23 4 views
10

I asked this question a while back। जवाब महान काम किया:क्या मैं एकाधिक कॉलम के आधार पर डेटाबेस डुप्लिकेट हटा सकता हूं? कॉलम के आधार पर डुप्लिकेट रिकॉर्ड हटाने के लिए

delete from tbl 
where id NOT in 
(
select min(id) 
from tbl 
group by sourceid 
) 

अब मैं एक simillar स्थिति लेकिन डुप्लिकेट रिकॉर्ड की परिभाषा एकाधिक स्तंभों पर आधारित है। मैं डुप्लिकेट रिकॉर्ड्स की पहचान करने के लिए इस उपरोक्त एसक्यूएल को कैसे बदल सकता हूं जहां एक अद्वितीय रिकॉर्ड को Col1 + Col2 + Col3 से संयोजित के रूप में परिभाषित किया गया है। क्या मैं ऐसा कुछ करूंगा?

delete from tbl 
where id NOT in 
(
select min(id) 
from tbl 
group by col1, col2, col3 
) 
+0

सिद्धांत अभी भी खड़ा है - इससे कोई फर्क नहीं पड़ता कि समूहांकन एक या कई स्तंभों से है या नहीं। आप समूह में केवल पहली पंक्ति को बनाए रखने जा रहे हैं। लेकिन - अगर आप मुझे यह कहते हुए कोई फर्क नहीं पड़ता - हटाए जाने से पहले अपना डेटा जांचना सुनिश्चित करें। चयन करने के लिए हटाएं और देखें कि क्या/जीवित नहीं रहेगा। –

+0

@ निकोला मार्कोविनोविच - ऐसा लगता है कि यह सही काम कर रहा है लेकिन सिर्फ – leora

+0

@leora की पुष्टि करना चाहता था, मुझे सिंटैक्स मिल गया है जिसे आप अवधारणात्मक/रिवर्स इंजीनियर के लिए बोझिल कर रहे हैं। और यह उन मामलों में अच्छी तरह से अनुवाद नहीं करता है जहां आईडी शून्य हो सकती है (क्योंकि 'इन नहीं' व्यवहार नहीं करता है क्योंकि जब आप नल शामिल होते हैं तो आप उम्मीद कर सकते हैं)। मुझे एहसास हुआ कि यहां एक कारक होने की संभावना नहीं है, लेकिन सीटीई के बारे में जानना महत्वपूर्ण है और उन मामलों के लिए EXISTS नहीं है जहां यह हो सकता है ... –

उत्तर

23

इससे पता चलता है पंक्तियों आप रखना चाहते हैं:

;WITH x AS 
(
    SELECT col1, col2, col3, rn = ROW_NUMBER() OVER 
     (PARTITION BY col1, col2, col3 ORDER BY id) 
    FROM dbo.tbl 
) 
SELECT col1, col2, col3 FROM x WHERE rn = 1; 

यह पंक्तियाँ आप हटाना चाहते हैं पता चलता है:

;WITH x AS 
(
    SELECT col1, col2, col3, rn = ROW_NUMBER() OVER 
     (PARTITION BY col1, col2, col3 ORDER BY id) 
    FROM dbo.tbl 
) 
SELECT col1, col2, col3 FROM x WHERE rn > 1; 

और एक बार आप खुश हैं कि इसके बाद के संस्करण दो सेट सही हैं, निम्नलिखित वास्तव में उन्हें हटा देंगे:

;WITH x AS 
(
    SELECT col1, col2, col3, rn = ROW_NUMBER() OVER 
     (PARTITION BY col1, col2, col3 ORDER BY id) 
    FROM dbo.tbl 
) 
DELETE x WHERE rn > 1; 

ध्यान दें कि सभी तीन प्रश्नों में, पहली 6 पंक्तियां समान हैं, और सीटीई के बाद ही बाद की क्वेरी बदल गई है।

+0

महान समाधान हारून! – mark1234

+0

शानदार समाधान। – CheGuevarasBeret

4

इसे आजमाएं। मैंने तीन कॉलम के साथ एक तालिका tblA बनाई है।

CREATE TABLE tblA 
(
id int IDENTITY(1, 1), 
colA int, 
colB int, 
colC int 
) 

और कुछ डुप्लिकेट मान जोड़े।

INSERT INTO tblA VALUES (1, 2, 3) 
INSERT INTO tblA VALUES (1, 2, 3) 
INSERT INTO tblA VALUES (4, 5, 6) 
INSERT INTO tblA VALUES (7, 8, 9) 
INSERT INTO tblA VALUES (7, 8, 9) 

यदि आप नीचे दिए गए कथन में एक डिलीट के साथ चयन को प्रतिस्थापित करते हैं तो आपके पास एकाधिक कॉलम काम को हटा देगा।

SELECT MIN(Id) as id 
FROM 
(
SELECT COUNT(*) as aantal, a.colA, a.colB, a.colC 
FROM tblA  a 
INNER JOIN tblA b ON b.ColA = a.ColA 
        AND b.ColB = a.ColB 
        AND b.ColC = a.ColC 
GROUP BY a.id, a.colA, a.colB, a.colC 
HAVING COUNT(*) > 1 
) c 
INNER JOIN tblA d ON d.ColA = c.ColA 
        AND d.ColB = c.ColB 
        AND d.ColC = c.ColC 
GROUP BY d.colA, d.colB, d.colC 
+1

"त्रिभुज स्वयं-शामिल" * काम करता है * लेकिन इतना गुंजाइश है ... – ErikE

संबंधित मुद्दे