我正在尝试生成一份报告,显示每个学生参加每个科目考试的次数,包括出勤率为零的学生和科目。我有三张桌子:
Students
、Subjects
和Examinations
。
输入:
Students
表:
+------------+--------------+
| student_id | student_name |
+------------+--------------+
| 1 | Alice |
| 2 | Bob |
| 13 | John |
| 6 | Alex |
+------------+--------------+
Subjects
表:
+--------------+
| subject_name |
+--------------+
| Math |
| Physics |
| Programming |
+--------------+
Examinations
表:
+------------+--------------+
| student_id | subject_name |
+------------+--------------+
| 1 | Math |
| 1 | Physics |
| 1 | Programming |
| 2 | Programming |
| 1 | Physics |
| 1 | Math |
| 13 | Math |
| 13 | Programming |
| 13 | Physics |
| 2 | Math |
| 1 | Math |
+------------+--------------+
输出:
+------------+--------------+--------------+----------------+
| student_id | student_name | subject_name | attended_exams |
+------------+--------------+--------------+----------------+
| 1 | Alice | Math | 3 |
| 1 | Alice | Physics | 2 |
| 1 | Alice | Programming | 1 |
| 2 | Bob | Math | 1 |
| 2 | Bob | Physics | 0 |
| 2 | Bob | Programming | 1 |
| 6 | Alex | Math | 0 |
| 6 | Alex | Physics | 0 |
| 6 | Alex | Programming | 0 |
| 13 | John | Math | 1 |
| 13 | John | Physics | 1 |
| 13 | John | Programming | 1 |
+------------+--------------+--------------+----------------+
说明: 结果表应包含所有学生和所有科目。 Alice 参加了 3 次数学考试,2 次物理考试,1 次编程考试。 Bob 参加了数学考试 1 次,编程考试 1 次,没有参加物理考试。 亚历克斯没有参加任何考试。 John 参加了数学考试 1 次、物理考试 1 次、编程考试 1 次。
这是我的代码:
SELECT s1.student_id, s1.student_name, e.subject_name, COUNT(e.subject_name) AS attended_exams
FROM Students s1
JOIN Examinations e ON e.student_id = s1.student_id
LEFT JOIN Subjects s2 ON s2.subject_name = e.subject_name
GROUP BY s1.student_id, s1.student_name, e.subject_name
ORDER BY s1.student_id ASC, s1.student_name ASC
这是我的输出:
+------------+--------------+---------------+----------------+
| student_id | student_name | subject_name | attended_exams |
+------------+--------------+---------------+----------------+
| 1 | Alice | Math | 3 |
| 1 | Alice | Physics | 2 |
| 1 | Alice | Programming | 1 |
| 2 | Bob | Math | 1 |
| 2 | Bob | Programming | 1 |
| 13 | John | Math | 1 |
| 13 | John | Physics | 1 |
| 13 | John | Programming | 1 |
+------------+--------------+---------------+----------------+
我仔细检查了解决方案,但没有发现任何差异。有人可以帮我修复我的代码以获得预期的输出吗?
使用
cross join
代替 left join
SELECT s.student_id, s.student_name, sub.subject_name,
COALESCE(COUNT(e.student_id), 0) AS attended_exams
FROM Students s
CROSS JOIN Subjects sub
LEFT JOIN Examinations e ON e.student_id = s.student_id
AND e.subject_name = sub.subject_name
GROUP BY s.student_id, s.student_name, sub.subject_name
ORDER BY s.student_id ASC, sub.subject_name ASC;