同一 table 上的多个 LEFT JOIN 语句
Multiple LEFT JOIN statements on the same table
我试图在同一个 table 上多次 LEFT JOIN,以获取特定主题的所有值。它像我想的那样工作,请参阅:http://sqlfiddle.com/#!9/9cda67/4
但是,使用上面的 fiddle,数据库 returns 每个不同的课程单独一行。我想使用 GROUP BY PersonID
对它们进行分组,但它只会采用第一个值(数学为 6)和所有其他列的 (null)
值。参见:http://sqlfiddle.com/#!9/9cda67/5
我需要更改什么才能让每个人获得一行,并将所有成绩填入各自的列(如果可用)?
MySQL 允许您在 SELECT
中包含不在 GROUP BY
中的列。这实际上违反了 ANSI 标准并且不受任何其他数据库的支持(尽管在某些情况下 ANSI 标准确实允许这样做)。结果是输出中单行的不确定值。
解决方案是聚合函数:
SELECT p.id AS PersonID, p.name AS PersonName,
max(pc1.grade) AS Math,
max(pc2.grade) AS Chemistry,
max(pc3.grade) AS Physics
FROM Person p LEFT JOIN
Person_Course pc
on p.id = pc.user_id LEFT JOIN
Course c on c.id = pc.course_id LEFT JOIN
Person_Course pc1
on pc1.id = pc.id AND pc1.course_id = 1 LEFT JOIN
Person_Course pc2
on pc2.id = pc.id AND pc2.course_id = 2 LEFT JOIN
Person_Course pc3
on pc3.id = pc.id AND pc3.course_id = 3
GROUP BY PersonID;
如果人们可以多次参加同一课程,您可能需要 group_concat()
。另外,不要对列名使用单引号。仅将它们用于字符串和日期常量。
将课程 ID 硬编码到代码中似乎不是个好主意。我会使用条件聚合更简单地写这个:
SELECT p.id AS PersonID, p.name AS PersonName,
max(case when c.name = 'Math' then pc.grade end) AS Math,
max(case when c.name = 'Chemistry' then pc.grade end) AS Chemistry,
max(case when c.name = 'Physics' then pc.grade end) AS Physics
FROM Person p LEFT JOIN
Person_Course pc
on p.id = pc.user_id LEFT JOIN
Course c
on c.id = pc.course_id
GROUP BY PersonID;
我试图在同一个 table 上多次 LEFT JOIN,以获取特定主题的所有值。它像我想的那样工作,请参阅:http://sqlfiddle.com/#!9/9cda67/4
但是,使用上面的 fiddle,数据库 returns 每个不同的课程单独一行。我想使用 GROUP BY PersonID
对它们进行分组,但它只会采用第一个值(数学为 6)和所有其他列的 (null)
值。参见:http://sqlfiddle.com/#!9/9cda67/5
我需要更改什么才能让每个人获得一行,并将所有成绩填入各自的列(如果可用)?
MySQL 允许您在 SELECT
中包含不在 GROUP BY
中的列。这实际上违反了 ANSI 标准并且不受任何其他数据库的支持(尽管在某些情况下 ANSI 标准确实允许这样做)。结果是输出中单行的不确定值。
解决方案是聚合函数:
SELECT p.id AS PersonID, p.name AS PersonName,
max(pc1.grade) AS Math,
max(pc2.grade) AS Chemistry,
max(pc3.grade) AS Physics
FROM Person p LEFT JOIN
Person_Course pc
on p.id = pc.user_id LEFT JOIN
Course c on c.id = pc.course_id LEFT JOIN
Person_Course pc1
on pc1.id = pc.id AND pc1.course_id = 1 LEFT JOIN
Person_Course pc2
on pc2.id = pc.id AND pc2.course_id = 2 LEFT JOIN
Person_Course pc3
on pc3.id = pc.id AND pc3.course_id = 3
GROUP BY PersonID;
如果人们可以多次参加同一课程,您可能需要 group_concat()
。另外,不要对列名使用单引号。仅将它们用于字符串和日期常量。
将课程 ID 硬编码到代码中似乎不是个好主意。我会使用条件聚合更简单地写这个:
SELECT p.id AS PersonID, p.name AS PersonName,
max(case when c.name = 'Math' then pc.grade end) AS Math,
max(case when c.name = 'Chemistry' then pc.grade end) AS Chemistry,
max(case when c.name = 'Physics' then pc.grade end) AS Physics
FROM Person p LEFT JOIN
Person_Course pc
on p.id = pc.user_id LEFT JOIN
Course c
on c.id = pc.course_id
GROUP BY PersonID;