SQL 聚合函数组合查询高级应用方法

2次阅读

SQL 聚合函数的核心在于与分组、HAVING 筛选、CASE WHEN 条件统计及窗口函数的灵活组合:1. GROUP BY 需包含 SELECT 中所有非聚合字段;2. HAVING 用于筛选分组后结果;3. CASE WHEN 实现单查询多维条件统计;4. 窗口函数支持分组聚合同时保留明细。

SQL 聚合函数组合查询高级应用方法

SQL 聚合函数本身不难,但真正提升分析效率的,是把它们和分组、过滤、窗口、子查询等机制灵活组合。关键不在“会用 COUNT”,而在“知道什么时候该用 COUNT + CASE WHEN,什么时候该嵌套 AVG(SUM()),什么时候必须加 HAVING 而不是 WHERE”。

用 GROUP BY + 聚合函数做多维分组统计

单字段分组太基础,实际业务常需按多个维度交叉分析。比如统计“每个城市、每种订单状态下的平均订单金额和订单数”:

SELECT city, status, AVG(amount) AS avg_amount, COUNT(*) AS order_cnt
  FROM orders
  GROUP BY city, status;

注意:SELECT 中所有非聚合字段(city、status)都必须出现在 GROUP BY 子句中;若漏掉某个字段,多数数据库会报错。

用 HAVING 精准筛选分组结果

WHERE 作用于行,HAVING 才作用于分组后的聚合结果。比如只看“订单数超 100 且平均金额高于 500”的城市:

SELECT city, COUNT(*) AS cnt, AVG(amount) AS avg_amt
  FROM orders
  GROUP BY city
  HAVING COUNT(*) > 100 AND AVG(amount) > 500;

常见误区:把聚合条件写在 WHERE 里(如 WHERE AVG(amount) > 500),语法直接报错——因为 WHERE 执行时还没分组,更没算出 AVG。

用 CASE WHEN + 聚合实现条件统计

一个查询里同时算“已支付订单数”、“未支付订单数”、“总金额”、“已支付金额”,不用多次 JOIN 或子查询:

  • 用 SUM(CASE WHEN status = ‘paid’ THEN 1 ELSE 0 END) 统计已支付笔数
  • 用 SUM(CASE WHEN status = ‘paid’ THEN amount ELSE 0 END) 算已支付金额
  • 用 COUNT(*) 和 SUM(amount) 得到全局总数与总额

SELECT
  COUNT(*) AS total_orders,
  SUM(CASE WHEN status = ‘paid’ THEN 1 ELSE 0 END) AS paid_cnt,
  SUM(CASE WHEN status = ‘paid’ THEN amount ELSE 0 END) AS paid_amt,
  AVG(amount) AS avg_per_order
  FROM orders;

用窗口函数扩展聚合能力

当需要“既看本组聚合值,又保留原始明细”时,窗口函数不可替代。例如:给每个用户的订单按时间排序,并计算该用户订单总金额、当前订单占该用户总额的比例:

SELECT
  user_id, order_time, amount,
  SUM(amount) OVER (PARTITION BY user_id) AS user_total,
  ROUND(amount * 100.0 / SUM(amount) OVER (PARTITION BY user_id), 2) AS pct_of_user
  FROM orders;

注意 PARTITION BY 相当于“按 user_id 分组做聚合,但不折叠行”,比 GROUP BY 更灵活;ORDER BY 可选,但加了就能支持累计求和(如 SUM(amount) OVER (PARTITION BY user_id ORDER BY order_time))。

星耀云
版权声明:本站原创文章,由 星耀云 2026-03-21发表,共计1510字。
转载说明:转载本网站任何内容,请按照转载方式正确书写本站原文地址。本站提供的一切软件、教程和内容信息仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。本站信息来自网络,版权争议与本站无关。
text=ZqhQzanResources