SQL作为操作关系型数据库的核心语言,其SELECT查询语句的执行顺序和书写顺序并不一致,理解这个差异是掌握复杂查询逻辑、优化查询性能的基础。很多新手写SQL时遇到问题,往往是因为不清楚语句实际的处理步骤。

SQL SELECT语句的标准书写顺序
我们日常写SELECT语句时,通常遵循以下顺序:
- SELECT:指定要查询的字段
- FROM:指定查询的数据表
- WHERE:过滤行数据
- GROUP BY:对数据进行分组
- HAVING:过滤分组后的数据
- ORDER BY:对结果排序
- LIMIT:限制返回的行数
SQL SELECT语句的实际执行顺序
数据库引擎处理SELECT语句时,并不会按照书写顺序执行,而是遵循以下优先级:
- FROM:首先确定要查询的数据来源,加载对应的表数据,如果有表关联会先处理关联逻辑
- ON:如果是多表关联查询,会先执行ON后的关联条件,过滤出符合关联规则的行
- WHERE:对FROM阶段得到的行数据进行过滤,排除不符合条件的行
- GROUP BY:将过滤后的行按照指定字段分组,相同分组字段的行会被归为同一组
- HAVING:对分组后的结果进行过滤,排除不符合条件的分组
- SELECT:选择要返回的字段,同时会计算SELECT后的表达式、聚合函数等
- DISTINCT:对SELECT阶段得到的结果去重
- ORDER BY:对最终的结果集按照指定字段排序
- LIMIT:截取指定行数的结果返回
执行顺序差异带来的常见问题
WHERE和HAVING的使用区别
因为WHERE执行在GROUP BY之前,所以WHERE中不能使用聚合函数,而HAVING执行在GROUP BY之后,可以使用聚合函数做过滤条件。比如要查询订单数大于5的用户,正确的写法是在HAVING中使用COUNT函数:
-- 错误写法,WHERE中不能用聚合函数 SELECT user_id, COUNT(order_id) AS order_cnt FROM order_table WHERE COUNT(order_id) > 5 GROUP BY user_id; -- 正确写法,HAVING中可以使用聚合函数 SELECT user_id, COUNT(order_id) AS order_cnt FROM order_table GROUP BY user_id HAVING COUNT(order_id) > 5;
SELECT别名的使用限制
SELECT阶段才会计算字段别名,所以WHERE和GROUP BY阶段无法使用SELECT中定义的别名。比如以下写法会报错:
-- 错误写法,WHERE中不能用SELECT定义的别名 SELECT user_id AS uid, user_name FROM user_table WHERE uid = 1001; -- 正确写法,直接用原字段名 SELECT user_id AS uid, user_name FROM user_table WHERE user_id = 1001;
多表关联查询的执行示例
假设我们有两个表,用户表user_table和订单表order_table,要查询每个用户的订单数量,且只返回订单数大于3的用户,按订单数降序排列,取前10条,完整的SQL和执行逻辑如下:
SELECT
u.user_id,
u.user_name,
COUNT(o.order_id) AS order_cnt
FROM user_table u
LEFT JOIN order_table o ON u.user_id = o.user_id
GROUP BY u.user_id, u.user_name
HAVING COUNT(o.order_id) > 3
ORDER BY order_cnt DESC
LIMIT 10;
这条语句的执行步骤是:
- 先处理FROM后的user_table和order_table,执行LEFT JOIN的关联条件u.user_id = o.user_id,得到关联后的临时数据集
- 执行GROUP BY,按照u.user_id和u.user_name分组
- 执行HAVING,过滤出订单数大于3的分组
- 执行SELECT,计算user_id、user_name和order_cnt字段
- 执行ORDER BY,按照order_cnt降序排序
- 执行LIMIT,返回前10条结果
执行顺序总结
牢记SQL SELECT的实际执行顺序是优化查询、排查问题的基础,核心要点可以总结为:先确定数据源,再做行过滤,然后分组过滤,接着选择字段,最后排序截取。日常写SQL时如果遇到逻辑不符合预期的情况,可以对照执行顺序一步步排查每一步的处理结果,就能快速定位问题所在。
SQLSELECT执行流程SQL执行顺序数据库查询修改时间:2026-06-21 23:51:28