首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> MySQL 資料庫 >> MySQL 綜合教學

MySQL 舊表去重遷移至新表並重新生成主鍵 ID 單條 SQL 實現

     編輯:MySQL 綜合教學

MySQL 單條 SQL 實現:舊表去重遷移新表並自動生成遞增主鍵

資料治理常見需求:將舊表 (含臟資料、無主鍵或主鍵不連續) 依業務鍵去重,遷移至新結構表並重新生成連續自增 ID。本文提供單條 INSERT ... SELECT 完美解決,無需臨時表、程式迴圈。

業務場景

  • 舊表 B:id, n1, n2, n3, n4, n5... 含重複資料、主鍵雜亂
  • 新表 A:id (PK AI), n1, n2, n3 空表,需去重後資料
  • 去重鍵:(n1, n2, n3) 組合唯一

單條 SQL 解決方案

INSERT INTO A (id, n1, n2, n3)
SELECT @row := @row + 1 AS id, t1.n1, t1.n2, t1.n3
FROM (
    SELECT DISTINCT n1, n2, n3 FROM B
) t1
CROSS JOIN (SELECT @row := 0) t2;

關鍵技術點解析

進階變體:指定排序後再編號

INSERT INTO A (id, n1, n2, n3)
SELECT @row := @row + 1, t1.n1, t1.n2, t1.n3
FROM (
    SELECT DISTINCT n1, n2, n3 FROM B ORDER BY n1, n2
) t1
CROSS JOIN (SELECT @row := 0) t2;

MySQL 8.0+ 現代寫法 (CTE + ROW_NUMBER)

WITH dedup AS (
    SELECT DISTINCT n1, n2, n3 FROM B
),
numbered AS (
    SELECT ROW_NUMBER() OVER (ORDER BY n1, n2) AS id, n1, n2, n3 FROM dedup
)
INSERT INTO A (id, n1, n2, n3)
SELECT id, n1, n2, n3 FROM numbered;
優勢:標準 SQL、可讀性高、支援複雜排序/分組編號、無用戶變數副作用。

大表效能優化建議

  1. 舊表 (n1,n2,n3) 建立**複合索引**加速 DISTINCT 掃描
  2. 分批遷移:WHERE n1 BETWEEN ... 分範圍執行多條 SQL
  3. 關閉 Binlog (會話級) 減少主從延遲:SET SESSION sql_log_bin = 0;
  4. 使用 LOAD DATA 先導出 CSV 再匯入 (最快)

驗證腳本

-- 行數一致性
SELECT COUNT(*) FROM A;
SELECT COUNT(DISTINCT n1,n2,n3) FROM B;

-- 主鍵連續性
SELECT MAX(id) - COUNT(*) + 1 AS gap_count FROM A; -- 應為 1

-- 業務鍵唯一性
SELECT n1,n2,n3, COUNT(*) FROM A GROUP BY n1,n2,n3 HAVING COUNT(*) > 1;
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
技術作用
SELECT DISTINCT n1,n2,n3依組合鍵去重,保留唯一業務記錄
CROSS JOIN (SELECT @row := 0)初始化用戶變數 @row = 0,產生單行虛表參與 JOIN
@row := @row + 1每行遞增 1,生成連續整數序列作為新主鍵
列順序對應id, n1, n2, n3 嚴格對應 SELECT 列順序