อีกวิธีที่เป็นไปได้ในการทำเช่นนี้คือ
;
--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
เป็นคำศัพท์ CTE ได้โดยตรง ดูstackoverflow.com/q/18439054/398670