SQL 聚合函数组合使用技巧解析

sql聚合函数不可直接嵌套,但可通过group by横向统计、子查询/cte实现聚合后再聚合、having过滤分组结果等方式组合使用。

SQL 聚合函数组合使用技巧解析

SQL 聚合函数本身不支持直接嵌套(如 COUNT(SUM(...)) 会报错),但通过分组、子查询、窗口函数或 HAVING 等方式,可以灵活组合多个聚合结果,解决“每类中最大销量的平均值”“订单数超5的客户总消费额”等实际问题。

用 GROUP BY + 多个聚合函数横向统计

在同一个查询中对同一组数据计算多个指标,是最常用也最高效的组合方式。关键在于明确分组维度,再对各列独立聚合。

  • 例如统计每个部门的员工数、平均薪资、最高薪资和薪资总和:

SELECT dept, COUNT(*) AS emp_count, AVG(salary) AS avg_sal, MAX(salary) AS max_sal, SUM(salary) AS total_sal<br>FROM employees<br>GROUP BY dept;

注意:所有非聚合字段(如 dept)必须出现在 GROUP BY 中;聚合函数之间互不影响,可自由搭配。

用子查询实现“聚合后再聚合”逻辑

当需要对聚合结果进一步计算(比如“各部门平均薪资的中位数”),需将第一层聚合作为子查询或 CTE,再在外层处理。

  • 示例:找出平均薪资高于公司整体平均值的部门

SELECT dept, AVG(salary) AS dept_avg<br>FROM employees<br>GROUP BY dept<br>HAVING AVG(salary) > (SELECT AVG(salary) FROM employees);

  • 更复杂场景(如求各部门平均薪资的中位数)可写成:

WITH dept_avgs AS (<br>  SELECT dept, AVG(salary) AS avg_sal FROM employees GROUP BY dept<br>)<br>SELECT PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY avg_sal) FROM dept_avgs;

用 HAVING 过滤聚合结果,替代 WHERE 的局限

WHERE 在分组前过滤行,无法使用聚合函数;HAVING 则专用于筛选分组后的聚合结果,是组合聚合逻辑的关键阀门。

  • 错误写法(WHERE 后跟聚合函数):WHERE COUNT(*) > 10 → 报错
  • 正确写法:GROUP BY user_id HAVING COUNT(*) >= 5 → 筛出下单≥5次的用户
  • 可叠加多个条件:HAVING AVG(amount) > 100 AND SUM(amount)

用窗口函数避免过度分组,保留明细与聚合并存

当既要原始记录(如每笔订单),又要所在客户/品类的统计值(如该客户的平均订单额),窗口函数比自连接或子查询更简洁高效。

  • 示例:显示每位客户的每笔订单,并附上该客户的订单总数和平均金额

SELECT<br>  customer_id,<br>  order_id,<br>  amount,<br>  COUNT(*) OVER (PARTITION BY customer_id) AS order_cnt,<br>  AVG(amount) OVER (PARTITION BY customer_id) AS avg_order_amt<br>FROM orders;

窗口函数不改变行数,适合做“带上下文的聚合”,且支持排序(ORDER BY ... ROWS BETWEEN)实现滚动统计。