SQL中如何对查询结果进行分组计数:COUNT与GROUP BY

张开发
2026/4/21 0:49:10 15 分钟阅读

分享文章

SQL中如何对查询结果进行分组计数:COUNT与GROUP BY
MySQL 5.7和PostgreSQL要求SELECT中非聚合字段必须出现在GROUP BY中或用聚合函数包裹否则报错COUNT(*)统计所有行COUNT(列名)仅统计该列非NULL值空组不会出现在GROUP BY结果中需用LEFT JOIN补全。GROUP BY 后漏写非聚合字段会报错MySQL 5.7 和 PostgreSQL 默认不允许 SELECT 列表里出现未出现在 GROUP BY 中、又没被聚合函数包裹的字段。比如写 SELECT user_id, name, COUNT(*) FROM orders GROUP BY user_idname 没参与分组也没聚合MySQL 会直接报 Expression #2 of SELECT list is not in GROUP BY clause。常见做法是要么把 name 加进 GROUP BY要么确认它和 user_id 是一对一关系后用 ANY_VALUE(name)MySQL或 MIN(name)通用兜底。PostgreSQL 更严格不支持 ANY_VALUE必须显式处理或改用子查询SQLite 默认宽松但开启 PRAGMA legacy_alter_table ON 后行为可能变化别依赖默认宽容如果只是想查每个用户订单数就只选 user_id 和 COUNT(*)别多带无关字段COUNT(*) vs COUNT(列名) 行为差异很大COUNT(*) 统计行数包括所有行哪怕整行都是 NULLCOUNT(列名) 只统计该列非 NULL 的值。比如 COUNT(email) 会跳过 email IS NULL 的记录。实际场景中容易踩坑想统计“有手机号的用户数”却写了 COUNT(*)结果把没填手机号的也算了进去。统计总记录数用 COUNT(*)性能通常最好优化器可走索引行数估算统计某字段有效值数量必须用 COUNT(字段名)不能靠 WHERE 字段名 IS NOT NULL 再套 COUNT(*) —— 逻辑等价但可读性差且 WHERE 过滤后丢失分组维度信息COUNT(1) 和 COUNT(*) 在绝大多数引擎里没区别别迷信“1 更快”空组无匹配数据不会出现在 GROUP BY 结果里GROUP BY 只返回满足 WHERE 条件的分组。比如查“每个部门的平均薪资”但某个部门没人那结果里根本不会出现这个部门的行 —— 不会显示 dept_name | NULL 或 0。 Tellers AI Tellers是一款自动视频编辑工具可以将文本、文章或故事转换为视频。

更多文章