首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

SQL查找兩表數據差異三大經典方案:NOT EXISTS、MINUS、GROUP BY HAVING

     編輯:MySQL 資料庫相關知識

問題定義

給定結構完全相同的兩張表Student_1、Student_2,包含NAME、AGE、SCORE三列。需找出任一表中存在但另一表不存在、或字段值不同的記錄。即全外連接差集(Full Outer Join Difference)。

方案一:NOT EXISTS 雙向查詢 + UNION ALL(通用標準SQL)

SELECT * FROM Student_1 S1
WHERE NOT EXISTS (
    SELECT * FROM Student_2 S2 
    WHERE S1.name = S2.name AND S1.age = S2.age AND S1.score = S2.score
)
UNION ALL
SELECT * FROM Student_2 S2
WHERE NOT EXISTS (
    SELECT * FROM Student_1 S1 
    WHERE S1.name = S2.name AND S1.age = S2.age AND S1.score = S2.score
);

優點:所有主流數據庫支持、正確處理NULL值、可利用索引。缺點:需掃描兩遍表、寫法冗長。

方案二:MINUS/EXCEPT 集合運算(Oracle/PostgreSQL/SQL Server)

(SELECT * FROM Student_1 MINUS SELECT * FROM Student_2)
UNION ALL
(SELECT * FROM Student_2 MINUS SELECT * FROM Student_1);

注意:MySQL不支持MINUS/EXCEPT(8.0仍不支持),僅適用於Oracle、PostgreSQL、SQL Server等。語義清晰、優化器友好。

方案三:UNION ALL + GROUP BY HAVING COUNT(*)=1(單掃描、MySQL首選)

SELECT DISTINCT name, age, score FROM (
    SELECT * FROM Student_1
    UNION ALL
    SELECT * FROM Student_2
) t
GROUP BY name, age, score
HAVING COUNT(*) = 1;

核心邏輯:UNION ALL合併保留重複→GROUP BY分組→HAVING COUNT(*)=1篩選只出現一次的行(即差異行)。

優勢:單次全表掃描、無子查詢、MySQL執行計劃友好、性能最優。前提:兩表結構完全一致,無NULL值干擾(NULL參與GROUP BY會單獨分組)。

性能對比與選型建議

方案適用場景MySQL支持性能
NOT EXISTS通用、表較小、需精確匹配✅中
MINUS/EXCEPTOracle/PG/SQL Server❌高
GROUP BY HAVINGMySQL大表、結構一致✅最高

MySQL環境下首選方案三;異構數據庫遷移或跨庫對比時,方案一通用性最強。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved