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

SQL 陳述式邏輯執行順序詳解:FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY → TOP

     編輯:關於SqlServer

核心觀念

SQL 是宣告式語言,撰寫順序 ≠ 執行順序。引擎依邏輯階段處理,每階段產生虛擬表供下一階段使用,最終結果返回給客戶端。

標準邏輯執行階段 (編號 = 執行順序)

順序階段關鍵字輸入/輸出
1FROMFROM <left_table>笛卡爾積 → 虛擬表 VT1
2ONON <join_condition>篩選 VT1 → VT2
3JOIN<join_type> JOIN <right_table>外部連接保留未匹配列 → VT3
4WHEREWHERE <condition>篩選 VT3 → VT4
5GROUP BYGROUP BY <col_list>分組 VT4 → VT5
6CUBE/ROLLUPWITH CUBE/ROLLUP超級群組 → VT6
7HAVINGHAVING <condition>篩選群組 VT6 → VT7
8SELECTSELECT <select_list>投影/運算 → VT8
9DISTINCTDISTINCT去重 VT8 → VT9
10ORDER BYORDER BY <col_list>排序 VT9 → 游標 VC10
11TOP/OFFSET-FETCHTOP (N) / OFFSET ... FETCH取前 N 列 → VT11 (最終結果)

關鍵推論

  1. WHERE 不能用別名:WHERE (第 4 階段) 早於 SELECT (第 8 階段) 定義別名。
  2. ORDER BY 可用別名:ORDER BY (第 10 階段) 晚於 SELECT,別名已存在。
  3. GROUP BY 必須包含非聚合欄位:SELECT 清單非聚合欄位必須在 GROUP BY,因 SELECT 階段才投影,GROUP BY 階段需知分組鍵。
  4. HAVING 篩選群組,WHERE 篩選列:HAVING 在 GROUP BY 之後,可用聚合函數;WHERE 在 GROUP BY 之前,不可用聚合函數。
  5. DISTINCT 內含排序/雜湊:會重新排序,前序 ORDER BY 失效 (參見 DISTINCT 與 ORDER BY 衝突)。
  6. ORDER BY 產生游標非表:ANSI 定義排序結果為游標,不可作為衍生表/視圖/CTV 子查詢 (除非搭配 TOP)。

錯誤範例與修正

-- 錯誤:視圖/衍生表含 ORDER BY
CREATE VIEW V_Orders AS SELECT * FROM Orders ORDER BY OrderDate;
-- Msg 1033: The ORDER BY clause is invalid in views...

-- 修正:移除 ORDER BY,或搭配 TOP 100 PERCENT (舊版技巧,新版優化器會忽略)
CREATE VIEW V_Orders AS SELECT TOP 100 PERCENT * FROM Orders ORDER BY OrderDate;

實務應用:優化思維對齊執行順序

  • 儘早篩選:WHERE 條件下推,減少後續階段處理列數。
  • 索引服務於早期階段:JOIN ON、WHERE、GROUP BY、ORDER BY 欄位建立索引,避免 Scan/Sort。
  • 避免 SELECT *:增加投影成本、阻礙覆蓋索引、網路傳輸浪費。
  • DISTINCT 慎用:若業務鍵已唯一 (PK/UK),移除 DISTINCT 省去排序/雜湊開銷。

結語

熟記 FROM → ON → JOIN → WHERE → GROUP BY → CUBE/ROLLUP → HAVING → SELECT → DISTINCT → ORDER BY → TOP 邏輯順序,是寫出高效、正確 SQL 的基石。每次編寫複雜查詢,心中跑一遍階段流程,即可預判別名可用性、聚合可用性、排序語意、結果集型別。

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