SELECT ...
UNION [ALL | DISTINCT]
SELECT ...
[UNION [ALL | DISTINCT] SELECT ...]
核心規則:
UNION = UNION DISTINCT(去重,需排序)UNION ALL 保留所有行(不去重,效率高)需用括號包裹各 SELECT,將 ORDER BY/LIMIT 放在最後:
(SELECT a FROM tbl WHERE a=10 AND b=1)
UNION
(SELECT a FROM tbl WHERE a=11 AND b=2)
ORDER BY a LIMIT 10;
⚠️ 不能 使用 表名.列名 引用,需用別名或列位置:
(SELECT a AS b FROM t) UNION (SELECT ...) ORDER BY b; -- ✅
(SELECT a AS b FROM t) UNION (SELECT ...) ORDER BY a; -- ❌ Unknown column 'a'
將子句放入括號內:
(SELECT a FROM tbl WHERE a=10 ORDER BY a LIMIT 10)
UNION
(SELECT a FROM tbl WHERE a=11 ORDER BY a LIMIT 10);
(SELECT * FROM blog WHERE top=1 ORDER BY created DESC)
UNION
(SELECT * FROM blog WHERE top=0 ORDER BY created DESC)
LIMIT 2, 3; -- 跳過前 2 條,取 3 條
⚠️ 兩側查詢列數必須一致,缺失列可用 NULL 佔位。
關鍵技巧:引入常量列 ord 作為第一排序鍵,實現分組優先級控制。
| 特性 | UNION (DISTINCT) | UNION ALL |
|---|---|---|
| 去重 | 是(全表排序去重) | 否 |
| 臨時表 | 需創建臨時表排序 | 直接合併結果流 |
| 磁盤溢寫風險 | 高(大數據量) | 低 |
| 適用場景 | 結果集可能重複、需去重 | 確認無重複、或允許重複 |
| 性能 | 慢 | 快(數倍) |
經驗法則: 除非業務確實需要去重,優先使用 UNION ALL。典型場景:當前表 + 歷史表、分庫分表合併查詢。
COLLATE 統一UNION ... LIMIT 10 限制的是合併後總行數,而非各側UNION ALL 或 UNIONUsing temporary、Using filesort靈活運用 UNION,能用單條 SQL 解決原本需多次查詢或應用層合併的複雜業務,是 SQL 進階的必修課。