Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What kind of Join to see non-existent values in Join table?

Tags:

mysql

I have the tables users, locations and a join table. The join table also has a rank value for each individual at that location, because those individuals have higher ranks at certain locations than at other locations.

users
=========
id | name
=========
 1 | john
 2 | bob
 3 | alex

locations
===============
id | name
===============
 1 | san diego
 2 | dallas
 3 | new york
 4 | denver

join_users_locations
==============================
user_id | location_id | rank
==============================
      2 |           1 | 4
      2 |           2 | 3
      2 |           4 | 2
      3 |           1 | 2
      3 |           2 | 4

You can see that in the join table a user is only listed if they have a rank at that location. They are not even in the table if their rank is zero/null.

I'm wanting to get query results like this:

name |  location | rank 
=======================
 bob | san diego | 4
 bob |    dallas | 3
 bob |  new york | 0
 bob |    denver | 2

As you can see, I want all locations to be in the list, even ones that the user isn't joined with (just give those fields a rank value of zero).

It's easy to get the list of locations and ranks for locations he/she is joined with:

SELECT
    u.name,
FROM users u
LEFT JOIN join_users_locations jul ON jul.user_id = u.id
LEFT JOIN locations l ON l.id = jul.location_id
WHERE u.id = 2

But that only lists what locations the user is joined with. I want to see the non-joined locations as well.

I know this is possible, but I'm not sure what the solution is. I've tried some different types of JOINs with various results.

SQL FIDDLE HERE

like image 413
Jake Wilson Avatar asked Oct 23 '22 06:10

Jake Wilson


1 Answers

You can do this with a CROSS JOIN from users to locations.

SELECT
    u.name,
    l.name AS location,
    IFNULL(jul.rank, 0) AS rank
FROM
    users u CROSS JOIN
    locations l LEFT JOIN
    join_users_locations jul 
        ON jul.user_id = u.ID 
        AND jul.location_id = l.id
WHERE u.id = 2
like image 160
Michael Fredrickson Avatar answered Nov 08 '22 10:11

Michael Fredrickson