首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

MS SQL Server 刪除重複資料保留首筆:SELECT INTO 暫存表法與 DISTINCT 限制說明

     編輯:PHP 相關知識

當資料表出現完全重複的資料列(所有欄位值皆相同),需刪除重複僅保留第一筆。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

預設資料庫選項 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; -- 允許大量作業

DISTINCT 的限制

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 匯出去重後再大量匯入。
  • SQL Server 2005+ 建議使用 ROW_NUMBER() OVER (PARTITION BY ... ORDER BY ...) 單一陳述式完成。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved