SQL查询语句的执行顺序
一、标准SQL查询结构
SELECT DISTINCT column1, aggregate_func(column2)
FROM table1
JOIN table2 ON table1.id = table2.id
WHERE condition1
GROUP BY column1
HAVING condition2
ORDER BY column3
LIMIT 10;
二、执行顺序详解(附步骤代码示例)
1. FROM & JOIN
确定数据来源,执行表连接生成中间结果集。
-- 第一步执行:加载表并连接
FROM table1
JOIN table2 ON table1.id = table2.id
2. WHERE
过滤不符合条件的行(在聚合)。
-- 第二步执行:筛选符合条件的行
WHERE condition1 -- 例如:table1.date > '2023-01-01'
3. GROUP BY
按指定列分组,为聚合做准备。
-- 第三步执行:分组
GROUP BY column1 -- 例如:按国家分组
4. HAVING
过滤不符合条件的分组(在聚合后过滤)。
-- 第四步执行:筛选分组
HAVING condition2 -- 例如:COUNT(*) > 10
5. SELECT
选择最终输出的列,计算表达式或聚合函数。
-- 第五步执行:选择列并计算
SELECT column1, COUNT(*) AS order_count
6. DISTINCT
去除重复行(如果有的话)。
-- 第六步执行:去重(如果有DISTINCT)
DISTINCT
7. ORDER BY
对结果集排序。
-- 第七步执行:排序
ORDER BY order_count DESC
8. LIMIT / OFFSET
限制返回的行数。
-- 第八步执行:限制结果数量
LIMIT 10
三、完整示例分步解析
示例数据表
orders
表:订单ID、客户ID、日期(order_date)customers
表:客户ID、国家(country)
目标查询
SELECT
country,
COUNT(*) AS order_count
FROM orders
JOIN customers ON orders.customer_id = customers.id
WHERE order_date >= '2023-01-01'
GROUP BY country
HAVING COUNT(*) > 10
ORDER BY order_count DESC
LIMIT 5;
分步执行过程
-
FROM + JOIN
- 将
orders
和customers
表连接,生成所有订单与客户国家组合的中间表。
- 将
-
WHERE
- 过滤
order_date >= '2023-01-01'
的订单。
- 过滤
-
GROUP BY
- 按
country
分组,每个国家对应一组订单。
- 按
-
HAVING
- 筛选订单数超过10的国家(
COUNT(*) > 10
)。
- 筛选订单数超过10的国家(
-
SELECT
- 选择
country
和订单数(COUNT(*) AS order_count
)。
- 选择
-
ORDER BY
- 按
order_count
降序排序。
- 按
-
LIMIT
- 返回前5个结果。
四、常见误区与注意事项
1. WHERE vs. HAVING
WHERE
在聚合前过滤行,不能使用聚合函数(如COUNT
)。HAVING
在聚合后过滤分组,必须使用聚合函数或分组列。
2. 别名使用范围
SELECT
别名(如order_count
)不能在WHERE
或HAVING
中使用(因为执行顺序在前),但可以在ORDER BY
中使用。
3. DISTINCT 与 GROUP BY
DISTINCT
和GROUP BY
都可能去重,但GROUP BY
更常用于聚合场景。
4. 窗口函数执行顺序
窗口函数(如 ROW_NUMBER()
)在 WHERE
之后执行,但位于 ORDER BY
之前。
五、执行顺序总结图表
1. FROM & JOIN → 2. WHERE → 3. GROUP BY → 4. HAVING → 5. SELECT → DISTINCT → 7. ORDER BY → 8. LIMIT
通过理解执行顺序,您可以更高效地优化查询逻辑,避免不必要的计算!