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人)
记住这个流程,面试时可以用"做菜步骤"来形象描述,保证面试官印象深刻!