我有一张表格,其中包含学生在某些科目中的成绩。
STUDENT_GRADES
id | studentid | subjectid | grade
-----------------------------------
1 | 1 | 1 | A+
2 | 1 | 2 | A
3 | 1 | 3 | A-
4 | 2 | 2 | A
5 | 2 | 3 | A-
6 | 3 | 2 | B
7 | 4 | 3 | B+
我还有另一个包含主题列表的表。
主题
subjectid | subjectname
-----------------------------
1 | Maths
2 | Science
3 | History
现在我必须按以下格式检索结果。
FORMATTED_GRADES
studentid | subjectid | grade
-----------------------------------
1 | 1 | A+
1 | 2 | A
1 | 3 | A-
2 | 1 | fail
2 | 2 | A
2 | 3 | A-
3 | 1 | fail
3 | 2 | B
3 | 3 | fail
4 | 1 | fail
4 | 2 | fail
4 | 3 | B+
FORMATTED_GRADES
包含来自 STUDENT_GRADES
的每个学生及其在每个科目中的成绩。如果 STUDENT_GRADES
中没有某个学生的成绩,则该学生的该科目成绩应为不及格。
最佳答案
您很可能还有另一个表 students
,其中 studentid
作为主键。在 CROSS JOIN
中使用它来形成一个笛卡尔积,每行对应学生和主题的组合:
SELECT student_id, subject_id, COALESCE(g.grade, 'fail') AS grade
FROM students t
CROSS JOIN subjects u
LEFT JOIN student_grades g USING (student_id, subject_id);
最重要的是,这包括所有科目都不及格的学生。如果 student_grades
中根本没有任何条目,从 student_grades
(like @Gordon demonstrates) 中提取唯一学生的尝试将错过这些。
假设 subjects
没有名为 student_id
的列并且 students
没有列 subject_id
。否则你必须使用更明确的 join syntax使用 ON
而不是使用 USING
的快捷方式。
当使用 USING
子句连接时,输出表中只有一个(必须相同的)连接列实例,因此我们不需要在 SELECT
中进行表限定> 列表(即使无论如何都会被允许)。
同时假设 student_grades.grade
是 character data type .否则您需要显式转换以在 COALESCE
中获得兼容的数据类型。喜欢:COALESCE(g.grade::text, 'fail')
关于sql - 添加缺失行的默认值(学生和科目的组合),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46267342/