Mysql

关注公众号 jb51net

关闭
首页 > 数据库 > Mysql > MySQL查询SQL语句执行顺序

MySQL查询SQL语句的执行顺序的方法

作者:学亮编程手记

本文详细介绍了MySQL SELECT语句各子句的逻辑执行顺序及各阶段作用,并结合常见场景说明执行流程,强调WHERE与HAVING区别、别名使用限制、JOIN条件及子查询执行特点,对优化和理解SQL查询有重要指导意义,需要的朋友可以参考下

标准执行顺序

MySQL在执行一条SELECT查询时,逻辑上的执行顺序如下:

FROM → WHERE → GROUP BY → HAVING → SELECT → DISTINCT → ORDER BY → LIMIT

让我详细解释每个阶段:

1. FROM阶段

首先确定数据来源,包括表连接操作。如果有JOIN,会先执行笛卡尔积或根据JOIN条件进行表连接。多个表的JOIN按从左到右的顺序执行。

2. WHERE阶段

对FROM阶段产生的结果集进行条件过滤,筛选出符合条件的行。此时还不能使用SELECT中定义的别名,因为SELECT还没执行。

3. GROUP BY阶段

按照指定的列对数据进行分组,为聚合函数的计算做准备。

4. HAVING阶段

对分组后的结果进行过滤,通常与聚合函数配合使用。HAVING可以使用SELECT中的别名(某些MySQL版本支持)。

5. SELECT阶段

选择要返回的列,执行计算、函数调用等操作,生成最终的列。

6. DISTINCT阶段

如果有DISTINCT关键字,对结果集去重。

7. ORDER BY阶段

对结果集进行排序。可以使用SELECT中定义的别名。

8. LIMIT阶段

限制返回的行数,通常用于分页。

常见场景示例

场景1:基础查询

SELECT name, age
FROM users
WHERE age > 18
ORDER BY age DESC
LIMIT 10;

执行顺序:FROM users → WHERE age > 18 → SELECT name, age → ORDER BY age DESC → LIMIT 10

场景2:聚合查询

SELECT department, COUNT(*) as emp_count, AVG(salary) as avg_salary
FROM employees
WHERE status = 'active'
GROUP BY department
HAVING COUNT(*) > 5
ORDER BY avg_salary DESC;

执行顺序:FROM employees → WHERE status = ‘active’ → GROUP BY department → HAVING COUNT() > 5 → SELECT department, COUNT(), AVG(salary) → ORDER BY avg_salary DESC

场景3:多表JOIN

SELECT u.name, o.order_date, o.amount
FROM users u
INNER JOIN orders o ON u.id = o.user_id
WHERE o.order_date > '2025-01-01'
ORDER BY o.order_date DESC;

执行顺序:FROM users u → INNER JOIN orders o → WHERE o.order_date > ‘2025-01-01’ → SELECT u.name, o.order_date, o.amount → ORDER BY o.order_date DESC

场景4:子查询

SELECT name, salary
FROM employees
WHERE salary > (SELECT AVG(salary) FROM employees)
ORDER BY salary DESC;

执行顺序:先执行子查询得到平均工资 → FROM employees → WHERE salary > 子查询结果 → SELECT name, salary → ORDER BY salary DESC

场景5:DISTINCT去重

SELECT DISTINCT city
FROM customers
WHERE country = 'China'
ORDER BY city;

执行顺序:FROM customers → WHERE country = ‘China’ → SELECT city → DISTINCT → ORDER BY city

场景6:复杂的多表关联与分组

SELECT d.name as dept_name, COUNT(e.id) as employee_count
FROM departments d
LEFT JOIN employees e ON d.id = e.department_id AND e.status = 'active'
WHERE d.region = 'East'
GROUP BY d.id, d.name
HAVING employee_count > 0
ORDER BY employee_count DESC
LIMIT 5;

执行顺序:FROM departments d → LEFT JOIN employees e (包含ON条件) → WHERE d.region = ‘East’ → GROUP BY d.id, d.name → HAVING employee_count > 0 → SELECT d.name, COUNT(e.id) → ORDER BY employee_count DESC → LIMIT 5

重要注意事项

WHERE vs HAVING的区别:WHERE在分组前过滤,不能使用聚合函数;HAVING在分组后过滤,可以使用聚合函数。

别名的使用限制:WHERE子句中不能使用SELECT中定义的别名,因为WHERE先于SELECT执行。但ORDER BY和HAVING可以使用别名。

JOIN的ON条件:在FROM阶段执行,早于WHERE条件,因此在LEFT JOIN中,ON条件和WHERE条件的效果可能不同。

子查询的执行:相关子查询可能会对外层查询的每一行都执行一次,非相关子查询通常只执行一次。

理解这个执行顺序对编写高效SQL、理解查询结果以及优化查询性能都非常重要。

以上就是MySQL查询SQL语句的执行顺序的方法的详细内容,更多关于MySQL查询SQL语句执行顺序的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文