मुझे @erwin-brandstetter का समाधान पसंद है, लेकिन मैं USING
के साथ समाधान दिखाना चाहता था कीवर्ड:
DELETE FROM table_with_dups T1
USING table_with_dups T2
WHERE T1.ctid < T2.ctid -- delete the "older" ones
AND T1.name = T2.name -- list columns that define duplicates
AND T1.address = T2.address
AND T1.zipcode = T2.zipcode;
यदि आप रिकॉर्ड्स को हटाने से पहले उनकी समीक्षा करना चाहते हैं, तो बस DELETE
. को बदलें SELECT *
. के साथ और USING
अल्पविराम के साथ ,
, यानी
SELECT * FROM table_with_dups T1
, table_with_dups T2
WHERE T1.ctid < T2.ctid -- select the "older" ones
AND T1.name = T2.name -- list columns that define duplicates
AND T1.address = T2.address
AND T1.zipcode = T2.zipcode;
अद्यतन:मैंने गति के लिए यहां कुछ अलग समाधानों का परीक्षण किया। यदि आप कई डुप्लिकेट की अपेक्षा नहीं करते हैं, तो यह समाधान उन लोगों की तुलना में बहुत बेहतर प्रदर्शन करता है जिनके पास NOT IN (...)
है क्लॉज के रूप में वे सबक्वेरी में बहुत सारी पंक्तियाँ उत्पन्न करते हैं।
यदि आप IN (...)
. का उपयोग करने के लिए क्वेरी को फिर से लिखते हैं तो यह यहां प्रस्तुत समाधान के समान ही प्रदर्शन करता है, लेकिन SQL कोड बहुत कम संक्षिप्त हो जाता है।
अपडेट 2:यदि आपके पास NULL
है कुंजी कॉलम में से एक में मान (जो आपको वास्तव में आईएमओ नहीं करना चाहिए), तो आप COALESCE()
का उपयोग कर सकते हैं उस कॉलम की स्थिति में, उदा.
AND COALESCE(T1.col_with_nulls, '[NULL]') = COALESCE(T2.col_with_nulls, '[NULL]')