SQL实现按年统计首末阶段参与人数的查询方法
动态统计各年份首尾阶段参与人数的SQL实现
不需要硬编码每个年份的最后阶段值,核心思路是先按年份分组动态计算每个年份对应的首阶段、末阶段值,再筛选匹配的记录做聚合即可。
通用兼容写法(支持所有主流SQL数据库)
SELECT t.Year, t.Stage, COUNT(t.Participant) AS Participants FROM -- 把下面的表名替换成你实际的表名 your_table t INNER JOIN ( SELECT Year, MIN(Stage) AS first_stage, MAX(Stage) AS last_stage FROM your_table GROUP BY Year ) year_stage_range ON t.Year = year_stage_range.Year WHERE t.Stage = year_stage_range.first_stage OR t.Stage = year_stage_range.last_stage -- 注意必须同时按年份、阶段分组,否则不同年份同阶段的数据会被合并统计 GROUP BY t.Year, t.Stage ORDER BY t.Year ASC, t.Stage ASC;
代码说明
- 子查询部分会按年份自动计算每个年份的最小阶段(首阶段)、最大阶段(末阶段),完全不需要手动写死阶段数字,适配任意年份阶段数不固定的场景
- 关联原表后仅保留首、末阶段的记录做人数统计,最终排序规则和需求一致
- 运行后输出结果和预期完全匹配:
| Year | Stage | Participants |
|---|---|---|
| 2000 | 1 | 3 |
| 2000 | 3 | 2 |
| 2001 | 1 | 3 |
| 2001 | 4 | 3 |
简洁写法(适配支持窗口函数的数据库:MySQL8.0+、PostgreSQL、SQL Server2012+等)
如果你的数据库环境支持窗口函数,可以不用做表关联,写法更简洁:
SELECT Year, Stage, COUNT(Participant) AS Participants FROM ( SELECT *, MIN(Stage) OVER (PARTITION BY Year) AS first_stage, MAX(Stage) OVER (PARTITION BY Year) AS last_stage FROM your_table ) t WHERE Stage IN (first_stage, last_stage) GROUP BY Year, Stage ORDER BY Year ASC, Stage ASC;
原代码问题修正
你之前写的SQL有两个明显问题:
GROUP BY仅写了Stage,会把不同年份相同阶段的参与者合并计数,结果错误,必须同时把Year加入分组字段- 末阶段值不能硬编码,通过上述动态计算最大阶段的方式即可解决
内容的提问来源于stack exchange,提问作者Daniel Milian
相关产品推荐
相关产品推荐

