简体   繁体   中英

MySQL LEFT OUTER JOIN not giving correct results

This is probably simple, but I can't see the issue...

I have a MySQL table which contains an index of mailing lists by title. That table is LISTS. Then there is a users table and a subscriptions table. The subscriptions table contains simple entries that link users to their mailing lists.

The columns of concern are:

USERS u_id
LISTS l_id
SUBS s_id, u_id, l_id

So when user 23 joins mailing list 7, the entry created in SUBS is:

s_id: 1 --
u_id: 23 --
l_id: 7

Here's the problem: When a user is looking at their subscriptions, I need to display a table that shows all mailing lists, each with a checkbox that is ticked if they are already subscribed to that list.

My SQL, which is wrong, but I'm not sure how, is here:

SELECT l.l_id, l.l_name, l.l_desc,
CASE
 WHEN s.u_id = '23' THEN 1 ELSE 0 
END
FROM lists as l
LEFT OUTER JOIN
subs as s
ON s.l_id = l.l_id 
GROUP BY l.l_id ASC

This should be presenting 1s to tick relevant boxes and 0s to leave them empty.

But the behavior is odd, because when I get * from subs, I see all the expected entires. The above SQL, however, returns several empty checkboxes where subscriptions exist. And even stranger, if all boxes are ticked, the SQL returns no ticks at all.

I've been fighting this thing for far too long. Could anyone offer a solution?

Thank you very much!

The problem isn't the LEFT JOIN , it is the aggregation. You need aggregation functions in the SELECT .

However, I don't think you need aggregation at all. Assuming that a user id only appears once in lists for a given list:

SELECT l.l_id, l.l_name, l.l_desc,
       (s.l_id is not null) as flag
FROM lists l LEFT OUTER JOIN
     subs s
     ON s.l_id = l.l_id AND s.u_id = 23;

You can express the query your way (with aggregation). It would look like:

SELECT l.l_id, l.l_name, l.l_desc,
       MAX(s.u_id = 23) as flag
FROM lists l LEFT OUTER JOIN
     subs s
     ON s.l_id = l.l_id 
GROUP BY l.l_id, l.l_name, l.l_desc;

You can also use MAX(CASE s.u_id = 23 THEN 1 ELSE 0 END) , but MySQL's boolean shorthand is more convenient and readable.

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