我有一张桌子,可以容纳某些科目的学生成绩。
P.c
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+
SUBJECTS
现在我必须以下列格式检索结果。
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
中的某个科目没有学生成绩,那么该科目的学生成绩应该会失败。
答案 0 :(得分:2)
您很可能还有另一个以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
。否则,您必须使用ON
更明确的join syntax而不是USING
的快捷方式。
当加入USING
子句时,输出表中只有一个(必然相同)连接列的实例,因此我们不需要SELECT
列表中的表限定(即使无论如何都会被允许)。
还假设student_grades.grade
是character data type。否则,您需要显式转换以在COALESCE
中获取兼容的数据类型。喜欢:COALESCE(g.grade::text, 'fail')
答案 1 :(得分:1)
使用cross join
生成行,使用left join
和coalesce()
来获取所需的数据:
select st.student_id, su.subject_id,
coalesce(sg.grade, 'fail') as grade
from (select distinct student_id from student_grades) st cross join
subjects su left join
student_grades sg
on sg.student_id = st.student_id and sg.subject_id = su.subject_id