插件窝 干货文章 SQL中select与having子句的执行顺序:到底谁先执行?

SQL中select与having子句的执行顺序:到底谁先执行?

HAVING salary SELECT department 232    来源:    2025-03-30

SQL中SELECT与HAVING子句的执行顺序

在SQL查询中,SELECT和HAVING子句的执行顺序是一个常见的困惑点。以下是SQL查询的逻辑执行顺序:

标准SQL查询执行顺序

  1. FROM - 确定数据来源
  2. WHERE - 过滤行数据
  3. GROUP BY - 对数据进行分组
  4. HAVING - 过滤分组后的数据
  5. SELECT - 选择要返回的列
  6. ORDER BY - 对结果进行排序
  7. LIMIT/OFFSET - 限制返回的行数

关键点说明

  • HAVING在SELECT之前执行:HAVING子句是在分组后对组进行过滤,此时SELECT中的列别名还不可用
  • SELECT中的别名不能在HAVING中使用:因为HAVING执行时SELECT还未处理
  • WHERE与HAVING的区别
    • WHERE在分组前过滤行
    • HAVING在分组后过滤组

示例说明

SELECT department, AVG(salary) AS avg_salary
FROM employees
WHERE hire_date > '2020-01-01'
GROUP BY department
HAVING AVG(salary) > 50000
ORDER BY avg_salary DESC;

执行顺序: 1. 从employees表获取数据 2. 应用WHERE条件过滤 3. 按department分组 4. 计算每组的平均工资 5. 使用HAVING过滤平均工资>50000的组 6. 选择department和avg_salary列 7. 按avg_salary降序排序

常见错误

错误写法(在HAVING中使用SELECT别名):

SELECT department, AVG(salary) AS avg_salary
FROM employees
GROUP BY department
HAVING avg_salary > 50000  -- 错误!HAVING执行时avg_salary还不存在

正确写法:

SELECT department, AVG(salary) AS avg_salary
FROM employees
GROUP BY department
HAVING AVG(salary) > 50000  -- 使用聚合函数而不是别名

理解这个执行顺序对于编写正确的SQL查询非常重要,特别是在处理分组和聚合函数时。