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

MySQL UNION 進階用法與排序技巧全解析

     編輯:MySQL 綜合教學

一、UNION 基礎語法

SELECT ...
UNION [ALL | DISTINCT]
SELECT ...
[UNION [ALL | DISTINCT] SELECT ...]

核心規則:

  • 所有 SELECT 的列數、順序、類型必須一致
  • 結果集列名取自第一個 SELECT
  • UNION = UNION DISTINCT(去重,需排序)
  • UNION ALL 保留所有行(不去重,效率高)

二、排序與 LIMIT 的正確姿勢

2.1 對整個 UNION 結果排序/限制

需用括號包裹各 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'

2.2 對單個 SELECT 排序/限制

將子句放入括號內:

(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);

三、實戰場景與進階技巧

3.1 置頂文章 + 普通文章分頁(經典 Blog 場景)

(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 佔位。

3.2 子查詢包裹實現雙向排序

3.3 模擬「前 N 條按點擊排序,其餘按時間排序」

關鍵技巧:引入常量列 ord 作為第一排序鍵,實現分組優先級控制。

四、UNION vs UNION ALL 性能對比

特性UNION (DISTINCT)UNION ALL
去重是(全表排序去重)否
臨時表需創建臨時表排序直接合併結果流
磁盤溢寫風險高(大數據量)低
適用場景結果集可能重複、需去重確認無重複、或允許重複
性能慢快(數倍)

經驗法則: 除非業務確實需要去重,優先使用 UNION ALL。典型場景:當前表 + 歷史表、分庫分表合併查詢。

五、常見陷阱避坑

  1. 隱式類型轉換:兩側對應列類型不一致會觸發隱式轉換,導致索引失效
  2. 字符集排序規則衝突:不同表字符集不同會報錯,需 COLLATE 統一
  3. ORDER BY 位置錯誤:只能在最後一個 SELECT 後或括號內
  4. LIMIT 邏輯誤解:UNION ... LIMIT 10 限制的是合併後總行數,而非各側

六、最佳實踐總結

  • ✅ 明確業務是否需要去重 → 選 UNION ALL 或 UNION
  • ✅ 統一兩側列定義:數量、順序、類型、字符集
  • ✅ 善用常量列實現分組排序優先級
  • ✅ 大數據量場景考慮分頁查詢優化,避免全量 UNION 後再 LIMIT
  • ✅ EXPLAIN 分析執行計劃,關注 Using temporary、Using filesort

靈活運用 UNION,能用單條 SQL 解決原本需多次查詢或應用層合併的複雜業務,是 SQL 進階的必修課。

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