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
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With