我在PostgreSQL数据库中有一个由学生和主题组成的数据集。关系看起来像:
学生:
id,
name,
。。。
学生ID |姓名|
1|Ramesh|
2|Suresh|
主题:
id,
name,
。。。
主题ID|名称|
1|数学|
2|科学|
Student_Subject:
id,
Student_id,
Subject_id,
可以想象,第三个表是一种表示多对多映射的形式。假设一个学生选择了3门科目,那么在student_subject表中,他将有3个与ID的映射。
学生可以选择的科目数量没有限制——可以是0到10之间的任何科目。
我需要创建一个SQL查询,它将以以下格式获取记录:
学生ID |学生姓名|数学|科学|…|历史1|Ramesh|Y|N|…|Y2|Suresh|N|Y|…|Y
Subject名称可以硬编码为列别名,这很好。
有人能建议一下如何做到这一点吗?
我尝试使用case when
技术作为:
选择stud.name,(当sub.name=‘Maths’然后‘Y’else‘N’结束时的情况("Maths",(当sub.name=‘Science’然后‘Y’else‘N’结束时的情况("Science",。。。来自学生内部联接student_subject在s.student_id=stud.id上sub.id=s_s.student_id上的内部联接主题sub
但这样我就不会让每个学生排一排了。如果学生选择了3个科目,我会得到3个不同的行,每行的每个科目都有一个Y值。
基于主题修复列表的静态解决方案:
您必须按学生对结果行进行分组,以便每个学生获得一行,对于每个组,使用bool_or()
聚合函数,当组中至少有一行返回True时,该函数将返回True:
select
stud.name,
bool_or(case when sub.name = 'Maths' then True else False end) "Maths",
bool_or(case when sub.name = 'Science' then True else False end) "Science",
...
from student stud
inner join student_subject s_s on s_s.student_id = stud.id
inner join subject sub on sub.id = s_s.student_id
group by stud.name
受试者列表可能发生变化时的动态解决方案:
请参阅如何在PostgresSQL select中动态添加列?