I have a table badges
that lists all available badges (badge_id, name, description, ...), a table users
that lists all users (user_id, name, ...) and a table users_badges
that saves all earned badges (id, badge_id, user_id).
If user 1 earns badge 5, an entry (x, 5, 1) is put into users_badges
(a user can only accquire each badge once).
To show each user which badges she has earned so far and which are still missing, I want to list her all badges whereas earned badges are colorful and non-earned badges gray.
For this I need an appropriate SQL query - and that's what I'm struggling with. A possible output would be a distinct list with all badges and the user_id of the particular user next to it; or NULL if she hasn't earned the badge yet.
First try:
SELECT * FROM badges
LEFT JOIN users_badges ON badges.id = users_badges.badge_id
WHERE users_badges.user_id = ".$row['user_id']." OR users_badges.user_id IS NULL
ORDER BY badges.id
Problem: This works only for the user that owns all the badges of the other users or more as the WHERE kicks out badges owned by others only.
Second try:
SELECT * FROM badges
LEFT JOIN users_badges ON badges.id = users_badges.badge_id
ORDER BY badges.id
Problem: Badges are listed multiple times if owned by multiple users. Adding a DISTINCT
would not solve the problem as the rows are already distinct (different user ids).
Maybe it is possible to go from this approach and kick out all rows with user_id
s other than the requested one, but only if she already has earned to badge (to ensure all non-owned badges are listed, too (in grey)?