Bunu yapmanın başka bir yolu da
;
--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)Yukarıda bir kravat durumunda korumak için hangi satır keyfi olarak kullanıyorum .
RowIDÖrneğin , en sonuncuyu korumak içinORDER BY RowID DESC
Uygulama Planları
Bunun için yürütme planı, kendi kendine katılmayı gerektirmediği için genellikle kabul edilen cevaptan daha basit ve daha etkilidir.

Ancak bu her zaman böyle değildir. Bir yerde GROUP BYçözüm yoluna gidilebilir bir durum olduğunu karma agrega bir dere agrega göre tercih edilecektir.
ROW_NUMBEROysa çözümü her zaman hemen hemen aynı planı verecektir GROUP BYstrateji daha esnektir.

Karma toplam yaklaşımını destekleyebilecek faktörler
- Bölümleme sütunlarında kullanışlı bir dizin yok
- her grupta nispeten daha fazla kopyaya sahip nispeten daha az grup
Bu ikinci durumun uç sürümlerinde (her birinde çok sayıda yinelemeye sahip çok az grup varsa), yeni bir tabloya tutmak için satırları eklemeyi ve ardından TRUNCATEorijinali yeniden kaydetmeyi ve günlüğü en aza indirmek için bunları kopyalamayı bir satırların çok yüksek bir oranı.
DELETE FROMdoğrudan bir CTE terimini kullanamazsınız . Bkz. Stackoverflow.com/q/18439054/398670