我很难知道从哪里开始做这件事。我想编写一个 SELECT 查询,该查询将返回特定班级中的所有学生以及他们各自学习的科目。但主题存储在另一个表的行中,我需要以某种方式使它们成为每个主题的新列。
我有四张桌子:
班级组:
身份证 | 班级名称 | 老师 |
---|---|---|
1 | 蓝色 | 史密斯先生 |
2 | 红色 | 布朗小姐 |
同学们:
身份证 | 类别ID | 姓氏 | 名字 |
---|---|---|---|
1 | 1 | 库珀 | 莎拉 |
2 | 2 | 琼斯 | 约翰 |
3 | 1 | 穆迪 | 克莱尔 |
4 | 1 | 巴金斯 | 佛罗多 |
课程:
身份证 | 班级 |
---|---|
1 | 地理 |
2 | 科学 |
3 | 英语 |
4 | 历史 |
5 | 西班牙语 |
班级_参加者
班级ID | 学生ID |
---|---|
1 | 1 |
1 | 2 |
1 | 4 |
2 | 1 |
2 | 5 |
3 | 2 |
3 | 3 |
3 | 4 |
4 | 1 |
4 | 2 |
4 | 3 |
我想编写一个 SELECT 查询来显示 Blue Class 的时间表,如下所示。
姓氏 | 名字 | 地理 | 科学 | 英语 | 历史 |
---|---|---|---|---|---|
库珀 | 莎拉 | 1 | 1 | 1 | |
穆迪 | 克莱尔 | 1 | 1 | 1 | |
巴金斯 | 佛罗多 | 1 | 1 | 1 |
由于蓝色班级中没有人学习西班牙语,所以我不需要为此开设专栏。
我想编写一个 SELECT 查询,该查询将返回特定班级中的所有学生以及他们各自学习的科目。但主题存储在另一个表的行中,我需要以某种方式使它们成为每个主题的新列
我想编写一个 SELECT 查询来显示 Blue Class 的时间表...
第一部分是简单的
JOIN
- 但第二部分(“...让它们成为一个新列” 和 “向我显示“”的时间表)在 SQL 中是不可能的,也不支持 通过 SQL 所基于的关系模型,因为您描述的“时间表”视图不是关系数据的示例(顺便说一句,术语“关系”不是指“关系”或外键;请参阅我链接到的 Codd 的论文)。
这里的基本规则之一(解释)是列是 static (即您的 SQL 查询直接定义列:例如 a
、
b
、
c
中的
SELECT a, b c FROM d
),因此在处理数据时可能存在也可能不存在(或者相反,不仅存在,而且具有非常高的基数)那么这一切都在行/元组中。因此,基于您尚未知道的查询结果的这些
未定义列的内部数据表示不能具有这些动态列,但这没关系,因为使用动态渲染表/数据网格的工作列最好由您的表示层完成(大概是 PHP 生成 HTML <table>
或您正在使用的某些报告/模板引擎?) - 但不使用仅 SQL。 (是的,你可以使用
Dynamic SQL 来破解它,但我们不要去那里。还有 PIVOT
/
UNPIVOT
,但这仍然需要你提前知道列是什么,当你写下查询)。无论如何,第一部分很容易完成:
SELECT
s.LastName,
s.FirstName,
c.ClassName
FROM
Class_attendees AS ca
INNER JOIN Students AS s ON ca.Student_ID = s.ID
INNER JOIN Classes A S c ON ca.Class_Id = c.ID
WHERE
s.ClassID = 1
ORDER BY
s.LastName,
s.FirstName,
s.ID /* Using this as a tie-breaker if two students have the same name */,
c.ClassName
...这会给你这个:
7ff2 | ||
de jure列,您仍然可以使用GROUP_CONCAT
来展平
结果:
WITH studentClasses AS (
SELECT
s.ID AS StudentId,
s.LastName,
s.FirstName,
c.ClassName
FROM
Class_attendees AS ca
INNER JOIN Students AS s ON ca.Student_ID = s.ID
INNER JOIN Classes A S c ON ca.Class_Id = c.ID
WHERE
s.ClassID = 1
)
SELECT
g.LastName,
g.FirstName,
GROUP_CONCAT( g.ClassName ORDER BY g.ClassName SEPARATOR ', ' ) AS Classes
FROM
studentClasses AS g
ORDER BY
s.LastName,
s.FirstName,
s.ID
给你...
名字 | 课程 | |
---|---|---|
莎拉 | 地理、科学、历史 | |
克莱尔 | 科学、英语、历史 | |
佛罗多 | 地理、科学、英语 |