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

SQL Server 查詢處理邏輯階段完解:從 FROM 到 SELECT 的執行順序

     編輯:關於SqlServer

核心觀念:SQL 不按書寫順序執行

在大多數程式語言中,程式碼依撰寫順序逐行執行;但 SQL 是宣告式語言,其邏輯處理順序與語法順序截然不同。理解這個順序是撰寫高效能查詢、正確使用別名、避免常見錯誤的關鍵。

邏輯查詢處理 11 階段(標準順序)

  1. FROM:對前兩個表執行笛卡爾積,產生虛擬表 VT1。
  2. ON:套用 JOIN 條件篩選 VT1,符合條件的列進入 VT2。
  3. OUTER JOIN:若指定外部聯結,將保留表中未配對的列加入 VT2,產生 VT3。多表時重複 1-3 步驟。
  4. WHERE:對 VT3 套用篩選條件,產生 VT4。
  5. GROUP BY:依群組欄位將 VT4 分組,產生 VT5。
  6. CUBE | ROLLUP:插入超級群組,產生 VT6。
  7. HAVING:對群組套用篩選,產生 VT7。
  8. SELECT:處理選取清單、彙總函數,產生 VT8。
  9. DISTINCT:移除重複列,產生 VT9。
  10. ORDER BY:排序 VT9,產生游標 VC10(此階段才可使用 SELECT 別名)。
  11. TOP:從 VC10 取指定筆數/比例,產生 VT11 並回傳呼叫端。

關鍵細節:ORDER BY 產生的是游標而非表

步驟 10 返回的是游標,不符合關聯式表的定義(集合無序)。因此包含 ORDER BY 的查詢不可作為表運算式(視圖、內嵌函數、衍生表、子查詢、CTE),除非同時指定 TOP 或 FOR XML。錯誤範例:

-- 無效的衍生表
SELECT * FROM (SELECT orderid, customerid FROM orders ORDER BY orderid) AS d;

-- 無效的視圖
CREATE VIEW my_view AS SELECT * FROM orders ORDER BY orderid;

執行時會拋出錯誤 1033:「ORDER BY 子句在視圖、內嵌函數、衍生表、子查詢和 CTE 中無效,除非同時指定 TOP 或 FOR XML。」

實務建議

  • 除非確定需要有序結果,否則勿加 ORDER BY,避免額外排序成本(索引掃描或 Sort 運算子)。
  • 若需在表運算式中排序,請改用 TOP 100 PERCENT ... ORDER BY(SQL Server 允許)或移至外層查詢。
  • 理解階段順序有助於除錯:例如 WHERE 不能使用 SELECT 定義的別名,因為 WHERE 在 SELECT 之前執行。

附錄:動態資料行轉置範例

將「學生-科目-分數」長表轉為寬表:

CREATE TABLE tb(姓名 VARCHAR(10), 課程 VARCHAR(10), 分數 INT);
INSERT INTO tb VALUES
('張三','語文',74),('張三','數學',83),('張三','物理',93),
('李四','語文',74),('李四','數學',84),('李四','物理',94);

SELECT 姓名,
       MAX(CASE 課程 WHEN '語文' THEN 分數 ELSE 0 END) AS 語文,
       MAX(CASE 課程 WHEN '數學' THEN 分數 ELSE 0 END) AS 數學,
       MAX(CASE 課程 WHEN '物理' THEN 分數 ELSE 0 END) AS 物理
FROM tb
GROUP BY 姓名;

結果:

姓名  語文  數學  物理
李四  74    84    94
張三  74    83    93
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved