添加缺失行的默认值(学生和科目的组合)

Add default for missing rows (combinations of students and subjects)

我有一个 table,其中包含学生在某些科目中的成绩。

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+

我还有另一个 table 包含主题列表。

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 和 his/her 年级的每个学生。如果STUDENT_GRADES中某科目没有学生成绩,则该学生该科目成绩应为不及格。

使用cross join生成行,left joincoalesce()得到你想要的数据:

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

您很可能还有另一个 table 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 () 中提取唯一学生的尝试将错过那些。

假设 subjects 没有名为 student_id 的列并且 students 没有名为 subject_id 的列。否则你必须使用更明确的 join syntaxON 而不是 USING.

的快捷方式

当使用 USING 子句连接时,输出中只有一个(必须相同的)连接列的实例 table,因此我们不需要 table 限定SELECT 列表(即使无论如何都会被允许)。

同时假设 student_grades.gradecharacter data type。否则您需要显式转换以获得 COALESCE 中的兼容数据类型。喜欢:COALESCE(g.grade::text, 'fail')