简体   繁体   中英

Which JOIN type do I use to display NULL values in this query?

I'm trying to join THREE tables.

The first table is transactions which contains details of "points" that students have earned. The relevant field here is Recipient_ID (the student receiving points).

The second table is purchases which contains details of "rewards" that students have purchased. The relevant fields here are Student_ID and Reward_ID .

The final table is rewards which details the rewards purchased. The relevant fields here are Reward_ID , Cost_to_User (the price the students pay for each reward; I'm currently not using this at all) and Title .


What I'm trying to do, provided with a specific list of student IDs, is display a list of students' points AND three most expensive reward purchases.

The SQL statement I've written thus far is:

SELECT
  t.Recipient_ID AS  `ID` ,
  SUM( t.Points ) AS  `Points Earned`,
  SUBSTRING_INDEX( GROUP_CONCAT(DISTINCT r.Title SEPARATOR ', '),', ',3 ) as `Rewards`
FROM  `transactions` t
JOIN `purchases` p ON t.Recipient_ID = p.Student_ID
JOIN `rewards` r ON p.Reward_ID = r.Reward_ID
WHERE  T.`Recipient_ID` 
  IN ( 90128, 90163, 34403, 35501 )
GROUP BY  t.`Recipient_ID`

This works to an extent - two students are displayed, with their point totals and latest rewards.

However, their point totals are vastly wrong, and I believe students aren't displaying if they haven't made any purchases.

I would still like to display the students if they've made no purchases.


I suspect it's my JOINs which are incorrect, but I also suspect GROUP_CONCAT isn't powerful enough to list the three most EXPENSIVE rewards. Do I need to change my JOINs, or do I need to use some sort of subquery?

Thanks in advance,

I think you should look at using a LEFT JOIN (See Visual Explanation of Joins ):

SELECT
  t.Recipient_ID AS  `ID` ,
  SUM( t.Points ) AS  `Points Earned`,
  SUBSTRING_INDEX( GROUP_CONCAT(DISTINCT r.Title SEPARATOR ', '),', ',3 ) as `Rewards`
FROM  `transactions` t
LEFT JOIN `purchases` p 
   ON t.Recipient_ID = p.Student_ID
LEFT JOIN `rewards` r 
  ON p.Reward_ID = r.Reward_ID
WHERE  T.`Recipient_ID` 
  IN ( 90128, 90163, 34403, 35501 )
GROUP BY  t.`Recipient_ID`

A LEFT JOIN will return all records from the transactions table even if there are no records in the purchases or rewards table.

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