postgrePostgres-SQL查询,从多对多映射中提取类似于跨选项卡的功能



我在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中动态添加列?

最新更新