如何统计满足Overall成绩≥Current成绩的ID数量及未通过ID?
问题解答
是否需要用CASE()函数转换成绩为数值?
是的,建议使用CASE()函数将成绩转换为数值。因为大多数数据库中字符串的排序逻辑是A < B < C < D < F,这和我们需要的成绩优先级(A > B > C > D > F)完全相反,直接用字符串比较会导致逻辑错误。转换为数值(如A=4、B=3、C=2、D=1、F=0)后,成绩的高低对应数值大小,比较逻辑清晰准确,不易出错。
SQL语句实现
1. 统计结果表(满足条件数、未通过数、总ID数)
先通过自连接将每个ID的Overall和Current成绩整合到同一行,再转换为数值进行比较统计:
WITH student_grades AS ( SELECT o.id, CASE o.grade WHEN 'A' THEN 4 WHEN 'B' THEN 3 WHEN 'C' THEN 2 WHEN 'D' THEN 1 WHEN 'F' THEN 0 END AS overall_score, CASE c.grade WHEN 'A' THEN 4 WHEN 'B' THEN 3 WHEN 'C' THEN 2 WHEN 'D' THEN 1 WHEN 'F' THEN 0 END AS current_score FROM your_table o INNER JOIN your_table c ON o.id = c.id AND o.status = 'Overall' AND c.status = 'Current' ) SELECT COUNT(CASE WHEN overall_score >= current_score THEN id END) AS pass_count, COUNT(CASE WHEN overall_score < current_score THEN id END) AS fail_count, COUNT(DISTINCT id) AS total_count FROM student_grades;
针对示例数据,执行后结果:
| pass_count | fail_count | total_count |
|---|---|---|
| 2 | 1 | 3 |
2. 未通过条件的ID列表
基于整合后的成绩数据,筛选出Overall成绩低于Current的ID及对应成绩:
WITH student_grades AS ( SELECT o.id, o.grade AS overall_grade, c.grade AS current_grade, CASE o.grade WHEN 'A' THEN 4 WHEN 'B' THEN 3 WHEN 'C' THEN 2 WHEN 'D' THEN 1 WHEN 'F' THEN 0 END AS overall_score, CASE c.grade WHEN 'A' THEN 4 WHEN 'B' THEN 3 WHEN 'C' THEN 2 WHEN 'D' THEN 1 WHEN 'F' THEN 0 END AS current_score FROM your_table o INNER JOIN your_table c ON o.id = c.id AND o.status = 'Overall' AND c.status = 'Current' ) SELECT id, overall_grade, current_grade FROM student_grades WHERE overall_score < current_score;
针对示例数据,执行后结果:
| id | overall_grade | current_grade |
|---|---|---|
| 345 | C | A |
补充说明
- 代码中的
your_table需要替换为你实际的数据表名称。 - 使用CTE(公共表表达式)是为了提升可读性,也可以将逻辑嵌套为子查询实现,效果一致。
- 自连接方式兼容性强,适用于MySQL、PostgreSQL、SQL Server等绝大多数数据库。
内容的提问来源于stack exchange,提问作者TingL
相关产品推荐
相关产品推荐

