當資料表出現完全重複的資料列(所有欄位值皆相同),需刪除重複僅保留第一筆。MS SQL Server 不支援 DELETE ... LIMIT 或 ROW_NUMBER()(2000 版無),常用暫存表搭配 SELECT INTO 完成。
-- 1. 將不重複資料寫入暫存表
SELECT DISTINCT * INTO #tmp_table FROM source_table;
-- 2. 清空原表
DELETE FROM source_table;
-- 3. 將去重後資料寫回
SELECT * INTO source_table FROM #tmp_table;
-- 4. 刪除暫存表
DROP TABLE #tmp_table;
預設資料庫選項 SELECT INTO 為關閉,需先開啟:
-- 方法 A:資料庫屬性對話框勾選 "Select into/bulkcopy"
-- 方法 B:T-SQL 指令
EXEC sp_dboption 'db_name', 'select into', 'true';
-- 或現代語法 (SQL Server 2005+)
ALTER DATABASE db_name SET RECOVERY BULK_LOGGED; -- 允許大量作業
SELECT DISTINCT * 僅能移除「完全相同」的資料列。若僅部分欄位重複(如 ID 重複但其他欄位不同),DISTINCT 無法解決,需改用分組、ROW_NUMBER() 或暫存表 + 自訂邏輯。
若表無主鍵,需依 ID 去重保留最早插入的資料列(假設 ID 為遞增):
-- 使用 IDENTITY 產生序號
SELECT IDENTITY(INT,1,1) AS seq, * INTO #tmp FROM source_table;
-- 保留每個 ID 的最小 seq (最早插入)
DELETE s FROM source_table s
JOIN (
SELECT ID, MIN(seq) AS min_seq FROM #tmp GROUP BY ID
) t ON s.ID = t.ID
WHERE NOT EXISTS (SELECT 1 FROM #tmp tmp WHERE tmp.ID = s.ID AND tmp.seq = t.min_seq);
DROP TABLE #tmp;
BCP 匯出去重後再大量匯入。ROW_NUMBER() OVER (PARTITION BY ... ORDER BY ...) 單一陳述式完成。