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

SQL Server存储过程中Group By分组统计班级数结果异常问题

问题原因

存储过程统计结果错误,核心是两处逻辑缺陷:

  • 班级数统计未去重:Class与Student是一对多关系,左连接后1个班级关联N名学生就会生成N行结果,直接用COUNT(Degree)统计行数,会把同一班级对应的重复学生行全部计入,导致数值偏大。比如测试数据中1st年级共2个班级,每个班级对应2名学生,连接后生成4行,计数就返回了错误值4。
  • 汇总行关联逻辑有隐患:UNION ALL的汇总部分使用INNER JOIN关联两表,如果后续新增没有学生的班级,这类班级会被内连接过滤,导致总班级数统计缺失。
修正方案

统计班级数时使用COUNT(DISTINCT C.CId)对班级ID去重计数,统计学生数时使用COUNT(S._SId)(COUNT会自动忽略左连接产生的NULL值,准确统计学生数量),汇总部分也改用左连接避免漏算无学生的班级。
修正后的存储过程代码如下:

ALTER PROCEDURE dbo.FirstReport
AS
BEGIN
    -- 按年级分组统计
    SELECT 
        Degree, 
        COUNT(DISTINCT C.CId) AS numberOfClasses, 
        COUNT(S._SId) AS numberOfStudents
    FROM Class C 
    LEFT OUTER JOIN Student S ON C.CId = S.StudentClass
    GROUP BY Degree

    UNION ALL

    -- 全量汇总统计
    SELECT 
        'SUM' AS Degree, 
        COUNT(DISTINCT C.CId), 
        COUNT(S._SId)
    FROM Class C 
    LEFT OUTER JOIN Student S ON C.CId = S.StudentClass;
END

执行后将返回正确结果:

DegreenumberOfClassesnumberOfStudents
1st24
2nd21
3rd10
SUM55

如果希望简化代码,也可以用WITH ROLLUP语法省略UNION ALL的重复查询,逻辑完全等价,后续维护更方便:

ALTER PROCEDURE dbo.FirstReport
AS
BEGIN
    SELECT 
        CASE WHEN GROUPING(C.Degree) = 1 THEN 'SUM' ELSE C.Degree END AS Degree,
        COUNT(DISTINCT C.CId) AS numberOfClasses,
        COUNT(S._SId) AS numberOfStudents
    FROM Class C 
    LEFT OUTER JOIN Student S ON C.CId = S.StudentClass
    GROUP BY C.Degree WITH ROLLUP;
END

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 13:33:17