PieCloudDB中统计学生各科目考试次数(含0值)的SQL问题
统计每个学生各科目考试次数(含未参与科目0值)
我在PieCloudDB数据库中有三张表:Student表、Subject表和Exam表,需要统计每个学生参与各科目考试的次数,未参与的科目需输出0。但我写的SQL查询无法输出考试次数为0的记录:
SELECT student_id, subject_name, COUNT(*) AS test_count FROM Examinations GROUP BY student_id, subject_name ORDER BY student_id, subject_name;
示例数据
Student表
| student_id | student_name |
|---|---|
| 1 | Alice |
| 2 | Bob |
| 6 | Joe |
| 13 | John |
Subject表
| subject_name |
|---|
| Math |
| Physics |
| Philosophy |
Exam表(原查询中名为Examinations)
| student_id | subject_name |
|---|---|
| 1 | Math |
| 1 | Physics |
| 1 | Philosophy |
| 2 | Philosophy |
| 1 | Physics |
| 1 | Math |
| 13 | Math |
| 13 | Philosophy |
| 13 | Physics |
| 2 | Math |
| 1 | Math |
期望输出
| student_id | student_name | subject_name | test_count |
|---|---|---|---|
| 1 | Alice | Math | 3 |
| 1 | Alice | Physics | 2 |
| 1 | Alice | Philosophy | 1 |
| 2 | Bob | Math | 1 |
| 2 | Bob | Physics | 0 |
| 2 | Bob | Philosophy | 1 |
| 6 | Joe | Math | 0 |
| 6 | Joe | Physics | 0 |
| 6 | Joe | Philosophy | 0 |
| 13 | John | Math | 1 |
| 13 | John | Physics | 1 |
| 13 | John | Philosophy | 1 |
解决方案
原查询只从Exam表取数据,自然无法包含没有考试记录的学生-科目组合。要解决这个问题,需要先生成所有学生和所有科目的笛卡尔积,再通过左连接关联Exam表,最后统计次数:
SELECT s.student_id, s.student_name, sub.subject_name, COUNT(e.student_id) AS test_count FROM Student s CROSS JOIN Subject sub LEFT JOIN Examinations e ON s.student_id = e.student_id AND sub.subject_name = e.subject_name GROUP BY s.student_id, s.student_name, sub.subject_name ORDER BY s.student_id, sub.subject_name;
关键说明:
CROSS JOIN Subject:生成每个学生与所有科目的组合,确保即使没有考试记录的组合也会被包含。LEFT JOIN Examinations:保留所有学生-科目组合,匹配到的考试记录会被关联,未匹配的则为NULL。COUNT(e.student_id):只统计匹配到的考试记录数,未匹配的NULL会被忽略,结果为0(如果用COUNT(*)会把NULL行也算进去,得到错误的1)。
内容的提问来源于stack exchange,提问作者Meliodas Dragon
相关产品推荐
相关产品推荐

