SQL的SELECT語句的執行順序可以用"做菜流程"來類比理解。雖然我們寫SQL時按SELECT…FROM…WHERE…順序寫,但數據庫執行順序完全不同。以下是通俗易懂的講解(附流程圖和示例):
🔧 執行順序流程圖:
FROM
→ JOIN
→ WHERE
→ GROUP BY
→ HAVING
→ SELECT
→ DISTINCT
→ ORDER BY
→ LIMIT/OFFSET
🍳 做菜版類比:
假設你要做一盤"宮保雞丁"
1. 準備食材(FROM+JOIN) → 2. 篩選新鮮食材(WHERE)
3. 按類別分組(GROUP BY)→ 4. 檢查調料是否達標(HAVING)
5. 選擇需要的配菜(SELECT)→ 6. 去掉重復的(DISTINCT)
7. 擺盤順序(ORDER BY)→ 8. 最終裝盤量(LIMIT)
📝 分步詳解(以查詢為例):
SELECT department, COUNT(*) as emp_count
FROM employees
WHERE salary > 5000
GROUP BY department
HAVING COUNT(*) > 3
ORDER BY emp_count DESC
LIMIT 2;
1?? FROM + JOIN(先確定數據源)
-- 第一步:先讀取employees表的所有數據
FROM employees
2?? WHERE(篩選行)
-- 第二步:過濾出工資>5000的記錄
WHERE salary > 5000
-- 注意:這里還不能使用SELECT中的別名emp_count!
3?? GROUP BY(分組)
-- 第三步:按部門分組
GROUP BY department
-- 現在數據被分成若干組,比如:[HR組, IT組, Finance組...]
4?? HAVING(篩選分組)
-- 第四步:只保留員工數>3的部門
HAVING COUNT(*) > 3
-- 這里可以用聚合函數,但WHERE不行
5?? SELECT(選擇列)
-- 第五步:選出部門名稱和統計數
SELECT department, COUNT(*) as emp_count
-- 此時才生成emp_count這個別名
6?? DISTINCT(去重)
-- 如果有DISTINCT,此時執行去重操作
-- 本例沒有使用
7?? ORDER BY(排序)
-- 第六步:按統計數降序排列
ORDER BY emp_count DESC
-- 這里可以使用SELECT階段生成的別名!
8?? LIMIT/OFFSET(最終限制)
-- 第七步:只取前2條結果
LIMIT 2
💡 關鍵記憶點:
- WHERE vs HAVING:WHERE過濾行,HAVING過濾分組
- 別名使用順序:ORDER BY可以使用SELECT的別名,WHERE不行
- 聚合函數位置:HAVING可用聚合函數,WHERE不可用
- 執行順序與書寫順序不同:FROM永遠最先執行
📊 最終結果示例:
假設原始數據:
部門 | 工資 |
---|---|
HR | 6000 |
HR | 5500 |
IT | 7000 |
IT | 7200 |
IT | 6800 |
Finance | 8000 |
經過各步驟處理后會得到:
department | emp_count |
---|---|
IT | 3 |
HR | 2 |
但因為HAVING COUNT(*)>3和LIMIT 2,最終只顯示IT部門(假設IT組實際有超過3人)
記住這個流程,面試時可以用"做菜步驟"來形象描述,保證面試官印象深刻!