資料表無主鍵或唯一限制時易產生重複列。本文提供兩種刪除重複資料的經典 SQL 寫法,適用於 SQL Server、MySQL、Oracle 等主流資料庫。
DELETE FROM table_name
WHERE id NOT IN (
SELECT MAX(id) -- 或 MIN(id)
FROM table_name
GROUP BY col1, col2, ... -- 判斷重複的欄位組合
)
✅ 優點:單一陳述式完成,邏輯直觀。
⚠️ 注意:NOT IN 遇到子查詢回傳 NULL 會導致全表刪除,確保分組欄位無 NULL 或改用 NOT EXISTS。
-- 1. 建立無重複暫存表
SELECT DISTINCT * INTO #temp FROM table_name
-- 2. 清空原表
DELETE FROM table_name
-- 或 TRUNCATE TABLE table_name (速度較快,需權限)
-- 3. 寫回去重後資料
INSERT INTO table_name SELECT * FROM #temp
-- 4. 清理
DROP TABLE #temp
✅ 優點:不依賴 ID 欄位,適用於全欄位重複。
⚠️ 注意:會重設 Identity 欄位值,若有外鍵參考需小心。
;WITH cte AS (
SELECT *,
ROW_NUMBER() OVER (PARTITION BY col1, col2 ORDER BY created_at DESC) AS rn
FROM table_name
)
DELETE FROM cte WHERE rn > 1
✅ SQL Server 2005+、Oracle、PostgreSQL、MySQL 8.0+ 支援。
✅ 可精確控制保留策略(最新、最舊、自訂排序)。
SELECT 驗證即將刪除的筆數