萬盛學電腦網

您现在的位置: 萬盛學電腦網 >> 程式設計 >  >> 資料庫 >> MySQL 教學

SQL ORDER BY 多欄位排序完全指南:ASC/DESC 混合、優先級、NULL 排序控制

SQL ORDER BY 支援多欄位排序,只需用逗號分隔,每欄位可獨立指定 ASC (升序) 或 DESC (降序)。本文詳細說明語法規則、優先級邏輯、NULL 值排序行為與跨資料庫差異,並提供實戰常見模式。

基本語法

SELECT col1, col2, col3 
FROM t1 
ORDER BY col1 DESC, col2 ASC, col3 DESC;
  • 按 col1 降序排序
  • col1 相同者,按 col2 升序
  • 前兩者皆相同者,按 col3 降序
  • 省略 ASC/DESC 預設 ASC

等價寫法對比

-- 寫法 1:簡潔 (f1 升序、f2 降序)
ORDER BY f1, f2 DESC

-- 寫法 2:明確 (推薦,可讀性佳)
ORDER BY f1 ASC, f2 DESC

-- 寫法 3:雙降序 (必須各自指定 DESC)
ORDER BY f1 DESC, f2 DESC

NULL 值排序行為 (關鍵差異)

MySQL 強制 NULL 排最後 (ASC)

ORDER BY (col IS NULL), col ASC;
-- col IS NULL 為真(1)排後,假(0)排前

實戰常見模式

資料庫ASC (升序)DESC (降序)控制語法
MySQLNULL 排最前NULL 排最後ORDER BY col IS NULL, col ASC (NULL 最後)
PostgreSQLNULL 排最後NULL 排最前ORDER BY col ASC NULLS LAST
OracleNULL 排最後NULL 排最前ORDER BY col ASC NULLS LAST
SQL ServerNULL 排最前NULL 排最後ORDER BY CASE WHEN col IS NULL THEN 1 ELSE 0 END, col

效能優化建議

  • 組合索引順序 = ORDER BY 順序:INDEX (status, created_at) 對應 ORDER BY status, created_at
  • 方向一致性:索引預設升序,ORDER BY a ASC, b DESC 無法完全使用索引 (MySQL 8.0 支援降序索引 INDEX (a ASC, b DESC))
  • 避免 filesort:EXPLAIN 出現 Using filesort 表示需優化索引或減少排序範圍
  • LIMIT 配合:ORDER BY ... LIMIT 10 可觸發「優先隊列排序」優化 (Priority Queue)

跨資料庫相容寫法

-- 標準 SQL (PostgreSQL, Oracle, MySQL 8.0+)
ORDER BY col1 ASC NULLS LAST, col2 DESC NULLS FIRST

-- MySQL 5.7 相容寫法
ORDER BY (col1 IS NULL), col1 ASC, col2 DESC
多欄位排序的核心是「優先級遞減」:最重要的排序鍵放最前,次重要次之,最後加上主鍵 id 保證結果確定性。記住 MySQL NULL 排序預設行為,必要時用 IS NULL 修正,索引順序務必與 ORDER BY 順序一致。
copyright © 萬盛學電腦網 all rights reserved
場景ORDER BY 子句說明
狀態優先 + 時間倒序status DESC, created_at DESC狀態 1(啟用) 在前,同狀態新資料在前
多維度權重排序(score1 * 0.6 + score2 * 0.4) DESC, id ASC加權分數主排,ID 兜底保證穩定
置頂 + 正常排序is_top DESC, sort_order ASC, id DESC置頂標記優先,其次人工排序,最後 ID 兜底
分組內排序category_id ASC, price DESC分組升序,組內價格降序