按指定列GROUPBY统计Excellent次数生成Final Result的SQL实现咨询
SQL按多列分组生成全组统一Final Result的实现方法
原代码错误分析
你的写法存在以下几个核心问题:
- 聚合查询语法错误:使用
GROUP BY后直接SELECT a.*不符合SQL规范,非分组聚合的列不能直接返回 - 逻辑混淆:将
Excellent计数逻辑和PASS/FAIL判断逻辑写在同一个COUNT函数内,执行顺序错误 - 符号错误:列名使用单引号包裹会被识别为字符串常量,判断条件符号
>被错误转义,FAIL前多写了多余单引号
最优实现方案(支持窗口函数的主流数据库)
用窗口函数PARTITION BY替代GROUP BY是最简便的写法,既可以统计分组内的Excellent次数,又能保留所有原始行,不需要额外关联子查询,兼容MySQL8+、PostgreSQL、SQL Server、Oracle等主流数据库。
SELECT Location, Sublocation, Area, -- 问题指定的分组列包含Area,示例未展示可按需保留 `Initial Results`, CASE WHEN COUNT(CASE WHEN `Initial Results` = 'Excellent' THEN 1 END) OVER ( PARTITION BY Location, Sublocation, Area ) >= 2 THEN 'PASS' ELSE 'FAIL' END AS `Final Results` FROM MyTable;
逻辑说明:
- 内层
CASE WHEN遇到Excellent返回1,否则返回NULL,COUNT统计非NULL值的数量,就是对应分组内Excellent的出现次数 OVER(PARTITION BY 分组列)会把计数结果同步到同分组的所有行,不会压缩原始行数据- 外层CASE判断计数是否≥2,输出对应的PASS/FAIL
低版本数据库兼容方案(不支持窗口函数场景)
如果是MySQL5.x这类不支持窗口函数的数据库,可以先做分组计数子查询,再和原表关联获取结果:
SELECT a.*, CASE WHEN b.excellent_cnt >= 2 THEN 'PASS' ELSE 'FAIL' END AS `Final Results` FROM MyTable a LEFT JOIN ( SELECT Location, Sublocation, Area, COUNT(CASE WHEN `Initial Results` = 'Excellent' THEN 1 END) AS excellent_cnt FROM MyTable GROUP BY Location, Sublocation, Area ) b ON a.Location = b.Location AND a.Sublocation = b.Sublocation AND a.Area = b.Area;
两种写法都可以匹配你给出的示例输入输出:Cafeteria分组Excellent计数为2返回PASS,Auditorium分组计数为1返回FAIL,完全符合规则要求。
内容的提问来源于stack exchange,提问作者Logan
相关产品推荐
相关产品推荐

