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

MySQL UNION 與 JOIN 差異深度解析:縱向合並 vs 橫向關聯、語法陷阱、性能選型指南

     編輯:MySQL 資料庫相關知識

UNION 與 JOIN 是多表數據融合的兩大核心操作,但本質截然不同:UNION 是「縱向疊加行」,JOIN 是「橫向拼接列」。本文通過實例對比、Hive 兼容性說明、UNION ALL 去重機制、GROUP BY 替代方案,幫助你精準選型。

核心差異一覽

維度UNIONJOIN
操作方向縱向 (行合並)橫向 (列拼接)
列要求列數、類型、順序**完全一致**無列要求,通過 ON 條件關聯
結果行數集合運算 (並集/全並集)笛卡爾積子集 (依條件過濾)
典型場景分表查詢合並、歷史+當前、多源匯總主外鍵關聯、多維度分析

UNION 實戰演示

-- 測試表
CREATE TABLE tmp_a (name VARCHAR(20), num INT);
CREATE TABLE tmp_b (name VARCHAR(20), num INT);
INSERT INTO tmp_a VALUES ('libingxue', 1001), ('yuwen', 1002);
INSERT INTO tmp_b VALUES ('libingxue', 1001), ('feiyao', 1003);

-- UNION (去重)
SELECT * FROM tmp_a UNION SELECT * FROM tmp_b;
-- 結果: 3 行 (libingxue 1001 僅保留 1 行)

-- UNION ALL (不去重)
SELECT * FROM tmp_a UNION ALL SELECT * FROM tmp_b;
-- 結果: 4 行 (libingxue 1001 保留 2 行)

Hive 兼容性注意

-- Hive 必須在子查詢中使用 UNION
SELECT * FROM (SELECT * FROM tmp_a UNION ALL SELECT * FROM tmp_b) t1;
-- 必須加別名 t1,且只支援 UNION ALL

JOIN 實戰演示

-- 同樣數據
SELECT * FROM tmp_a a JOIN tmp_b b ON a.name = b.name;
-- 結果: 1 行 (libingxue 1001 | libingxue 1001) - 內連接

SELECT * FROM tmp_a a LEFT JOIN tmp_b b ON a.name = b.name;
-- 結果: 2 行 (yuwen 1002 | NULL NULL) - 左連接保留左表所有行

等價轉換:UNION ALL ↔ JOIN + GROUP BY

-- 場景: 兩表結構相同,需合並去重
-- 方案 A: UNION ALL + GROUP BY
SELECT user_id, shop_id, MAX(auction_id), MAX(search_time)
FROM (
    SELECT * FROM tmp_resource
    UNION ALL
    SELECT * FROM tmp_result
) t1
GROUP BY user_id, shop_id;

-- 方案 B: JOIN (需主鍵關聯)
SELECT t1.user_id, t1.shop_id, t2.auction_id, t2.search_time
FROM tmp_resource t1
JOIN tmp_result t2 ON t1.user_id = t2.user_id AND t1.shop_id = t2.shop_id;

性能選型決策樹

  1. 列結構是否相同? → 是 → 考慮 UNION;否 → 必須 JOIN
  2. 需要去重? → 是 → UNION / UNION ALL + GROUP BY;否 → UNION ALL
  3. 數據量級? → 百萬級+ → UNION ALL 避免去重排序開銷;小表 → UNION 可接受
  4. 是否需保留來源標識? → 是 → SELECT *, 'source_a' AS src FROM a UNION ALL SELECT *, 'source_b' FROM b

經典表結構 UNION 示例

Table1 結構

Table2 結構

UNION 結果

SELECT * FROM Table1 UNION SELECT * FROM Table2;

避坑指南

坑 1:UNION 隱式去重導致性能暴跌
大數據量必用 UNION ALL + 應用層/索引去重
坑 2:列順序/類型不一致報錯
強制對齊:SELECT col1, CAST(col2 AS INT), col3 FROM a UNION SELECT col1, col2, col3 FROM b
坑 3:JOIN 無條件產生笛卡爾積
永遠加 ON 條件,或用 CROSS JOIN 顯式聲明
坑 4:LEFT JOIN 右表非唯一導致行數膨脹
參考 LEFT JOIN 右表非唯一解決方案
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved