ऐसा करने का एक और संभावित तरीका है
;
--Ensure that any immediately preceding statement is terminated with a semicolon above
WITH cte
AS (SELECT ROW_NUMBER() OVER (PARTITION BY Col1, Col2, Col3
ORDER BY ( SELECT 0)) RN
FROM #MyTable)
DELETE FROM cte
WHERE RN > 1;
मैं ORDER BY (SELECT 0)
ऊपर का उपयोग कर रहा हूं क्योंकि यह मनमाना है जो टाई की स्थिति में संरक्षित करने के लिए है।
RowID
उदाहरण के लिए आप उपयोग कर सकते हैं के लिए नवीनतम एक को संरक्षित करने के लिएORDER BY RowID DESC
निष्पादन योजनाएं
इसके लिए निष्पादन योजना अक्सर सरल और अधिक कुशल होती है क्योंकि स्वीकृत उत्तर में इसे स्वयं शामिल होने की आवश्यकता नहीं होती है।
हालांकि यह हमेशा मामला नहीं है। एक जगह जहां GROUP BY
समाधान को प्राथमिकता दी जा सकती है, वह स्थिति है जहां एक हैश एग्रीगेट को एक स्ट्रीम एग्रीगेट की प्राथमिकता में चुना जाएगा।
ROW_NUMBER
समाधान हमेशा काफी एक ही योजना दे देंगे जबकि GROUP BY
रणनीति अधिक लचीला है।
जो कारक हैश एग्रीगेट दृष्टिकोण के पक्ष में हो सकते हैं
- विभाजन कॉलम पर कोई उपयोगी सूचकांक नहीं
- प्रत्येक समूह में अपेक्षाकृत कम डुप्लिकेट वाले अपेक्षाकृत कम समूह
इस दूसरे मामले के चरम संस्करणों में (यदि प्रत्येक में कई डुप्लिकेट वाले बहुत कम समूह हैं) एक भी एक नई तालिका में रखने के लिए पंक्तियों को सम्मिलित करने पर विचार कर सकता है, फिर TRUNCATE
मूल को कॉपी करना और उन्हें हटाने की तुलना में लॉगिंग को कम करने के लिए वापस कॉपी करना पंक्तियों का बहुत उच्च अनुपात।
DELETE FROM
सीधे सीटीई शब्द नहीं कर सकते । देखें stackoverflow.com/q/18439054/398670