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

MySQL UNION 與 ORDER BY 優先級詳解:括號消除歧義、LIMIT 配合與去重行為

     編輯:MySQL 綜合教學

前言

UNION 與 ORDER BY 結合時,優先級歧義常導致結果不符預期。MySQL 官方文檔建議顯式加括號明確語義。本文通過實測案例,詳細解析三種寫法的差異、LIMIT 的關鍵作用、UNION 三種變體的去重行為。

一、優先級歧義與括號消歧

場景 1:對 UNION 結果整體排序

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

→ 先 UNION,再對合併結果集 ORDER BY。

場景 2:對單個 SELECT 子查詢排序

(SELECT a FROM tbl WHERE a=10 AND b=1 ORDER BY a LIMIT 10)
UNION
(SELECT a FROM tbl WHERE a=11 AND b=2 ORDER BY a LIMIT 10);

→ 每個子查詢各自排序並 LIMIT,再 UNION 合併(不保證全局有序)。

場景 3:無括號(MySQL 預設行為)

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;

實測結果:MySQL 預設按場景 1 執行(先 UNION 後 ORDER BY)。但強烈建議加括號,消除歧義、提升可讀性、避免版本差異。

二、ORDER BY 與 LIMIT 的關鍵綁定規則

單個 SELECT 子句中的 ORDER BY 必須配合 LIMIT 才生效。否則優化器會將其視為無意義排序並直接移除。

-- 生效:有 LIMIT
(SELECT a FROM tbl WHERE a=10 ORDER BY a LIMIT 10)

-- 失效:無 LIMIT,ORDER BY 被優化掉
(SELECT a FROM tbl WHERE a=10 ORDER BY a)

三、UNION 三種變體去重行為

語法去重效能使用建議
UNION✅ 去重(相當於 UNION DISTINCT)需排序/哈希去重,較慢業務要求結果唯一
UNION DISTINCT✅ 明確去重同 UNION語義更清晰
UNION ALL❌ 不去重,直接合併所有行最快,無額外開銷明確允許重複、或已知無重複、效能敏感場景

實戰範例

-- 去重
SELECT id FROM t1 WHERE status=1
UNION
SELECT id FROM t2 WHERE status=1;

-- 不去重,效能更好
SELECT id FROM t1 WHERE status=1
UNION ALL
SELECT id FROM t2 WHERE status=1;

四、進階:UNION 與 ORDER BY、LIMIT 組合模式

模式 1:分頁查詢多表聯合

(SELECT id, title, 'news' AS type FROM news WHERE cat_id=1 ORDER BY id DESC LIMIT 10)
UNION ALL
(SELECT id, title, 'blog' AS type FROM blog WHERE cat_id=1 ORDER BY id DESC LIMIT 10)
ORDER BY id DESC LIMIT 10;

→ 各表取 Top 10,合併後再取 Top 10。適用於「多表聯合分頁」但無法保證全局準確分頁(需應用層合併或全局視圖)。

模式 2:異構查詢合併去重

(SELECT email FROM users WHERE active=1)
UNION
(SELECT email FROM subscribers WHERE confirmed=1)
UNION
(SELECT email FROM leads WHERE opted_in=1)
ORDER BY email;

→ 三源郵箱去重合併,最終有序輸出。

五、常見坑點避雷

  1. 欄位數/類型不匹配:各 SELECT 欄位數必須相同,對應位置類型兼容(隱式轉換可能導致精度損失)
  2. ORDER BY 欄位引用:建議用別名或位置序號(ORDER BY 1),避免歧義
  3. UNION ALL 避免不必要去重:明知無重複或允許重複時,堅決用 UNION ALL
  4. 大結果集 UNION 記憶體壓力:去重需臨時表,超過 tmp_table_size/max_heap_table_size 會落盤,極慢

結語

UNION 與 ORDER BY 的優先級歧義,加括號即可徹底解決。記住:子查詢 ORDER BY 必配 LIMIT,去重用 UNION,不去重用 UNION ALL。將這些規範寫入團隊 SQL 開發規範,能避免 90% 的聯合查詢 Bug。

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