简体   繁体   中英

Multiple LEFT JOIN statements on the same table

I'm trying to LEFT JOIN on the same table multiple times, to get all the values of the specific topics. It works like I thought it would, see: http://sqlfiddle.com/#!9/9cda67/4

However, using the above fiddle, the database returns a single row for each different course. I'd like to group them, using GROUP BY PersonID , but then it would only take the first value (a 6 for Math) and a (null) value for all the other columns. See: http://sqlfiddle.com/#!9/9cda67/5

What do I need to change so that I get single row per Person, with all the grades filled in into their respective columns (when available)?

MySQL allows you to include columns in a SELECT that are not in the GROUP BY . This actually violates the ANSI standard and is not supported by any other database (although in some cases the ANSI standard does allow it). The result is indeterminate values from a single row in the output.

The solution is aggregation functions:

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;

You might want group_concat() if people could take the same course multiple times. Also, don't use single quotes for column names. Only use them for string and date constants.

Hardwiring the course ids into the code seems like a bad idea. I would write this more simply using conditional aggregation:

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;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM