You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SQL聚合函数在SELECT与HAVING中的使用规则问询

SQL聚合函数使用规则与SELECT子句执行时机解析

一、聚合函数在SELECT和HAVING中的使用规则

HAVING的核心作用是过滤分组后的结果集,它只能基于分组字段(GROUP BY中指定的字段)或聚合函数设定条件;而SELECT中的聚合函数,本质是定义最终要输出的聚合计算结果列,属于结果展示环节。

举两个实际例子对比:

  • 仅在SELECT中使用聚合函数:
SELECT department, COUNT(*) AS employee_count 
FROM employees 
GROUP BY department;

这会返回所有部门的员工数量,不管每个部门人数多少。

  • 同时在SELECT和HAVING中使用聚合函数:
SELECT department, COUNT(*) AS employee_count 
FROM employees 
GROUP BY department 
HAVING COUNT(*) >= 10;

这只会返回员工数量≥10的部门,结果和第一个查询明显不同。

关键规则:

  • SELECT里的聚合函数:用来生成最终展示的聚合统计值,可给列设置别名方便后续引用(但仅在ORDER BY等后续步骤生效)。
  • HAVING里的聚合函数:用来筛选分组,只有满足聚合条件的分组才会进入最终结果集;注意HAVING不能直接使用SELECT中定义的列别名,因为执行顺序上HAVING先于SELECT。

二、SELECT子句的实际执行时机

你对SELECT“按指定格式展示列”的理解没错,但SQL的执行顺序并不是从SELECT开始的,实际执行流程大致是:

  1. FROM:确定查询的数据源(表、视图等)
  2. WHERE:逐行过滤原始数据(此时还未分组,不能使用聚合函数)
  3. GROUP BY:将过滤后的行按指定字段分组
  4. HAVING:过滤分组后的结果集(可使用聚合函数)
  5. SELECT:选择要展示的列(包括分组字段、聚合计算结果,此时可设置列别名)
  6. ORDER BY:对最终结果排序(可使用SELECT中设置的别名)

正是因为HAVING执行在SELECT之前,所以HAVING里无法识别SELECT定义的别名,必须直接写聚合函数或分组字段。

三、你的实验结果相同的原因

你两次查询结果一致,大概率是因为添加的HAVING条件没有排除任何分组。比如你用了HAVING COUNT(*) = COUNT(*)这种恒成立的条件,或者HAVING SUM(salary) > 0但所有分组都满足这个条件,所以最终结果和仅在SELECT使用聚合函数的情况没有差异。换一个有实际筛选效果的HAVING条件(比如HAVING COUNT(*) > 5),就能看到明显的结果区别。

内容的提问来源于stack exchange,提问作者Dan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 23:25:02