我有一个表badges
,列出了所有可用的徽章(badge_id、name、description,...),表users
列出了所有用户(user_id、name) ,...)和一个表users_badges
,用于保存所有获得的徽章(id、badge_id、user_id)。
如果用户 1 获得徽章 5,则会将条目 (x, 5, 1) 放入 users_badges
中(每个用户只能获得每个徽章一次)。
为了向每个用户显示她到目前为止已获得的徽章以及尚未获得的徽章,我想列出她的所有徽章,而获得的徽章是彩色的,非获得的徽章是灰色的。
为此,我需要一个适当的 SQL 查询 - 这就是我正在努力解决的问题。可能的输出是一个不同的列表,其中包含所有徽章以及旁边特定用户的 user_id;如果她尚未获得徽章,则为 NULL。
第一次尝试:
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
问题:这仅适用于拥有其他用户的所有徽章或更多徽章的用户,因为 WHERE 仅踢出其他人拥有的徽章。
第二次尝试:
SELECT * FROM badges
LEFT JOIN users_badges ON badges.id = users_badges.badge_id
ORDER BY badges.id
问题:如果徽章由多个用户拥有,则会多次列出。添加 DISTINCT
并不能解决问题,因为行已经不同(不同的用户 ID)。
也许可以从这种方法出发,剔除所请求的以外的所有带有 user_id
的行,但前提是她已经获得了徽章(以确保列出所有非拥有的徽章,也是(灰色)?
最佳答案
对数据结构做出一些假设,我为此示例创建了虚拟表:
create table #badges
(
badge_id int,
[name] varchar(50),
[description] varchar(50)
)
create table #users
(
[user_id] int,
[name] varchar(50)
)
create table #users_badges
(
id int,
badge_id int,
[user_id] int
)
insert into #badges
values
(1,'Starter Badge','It''s your first time.'),
(2,'Rookie Badge','You''re just getting started.'),
(3,'Intermediate Badge','Now you''re starting to get the hang of this.'),
(4,'Expert Badge','You are a master!')
insert into #users
values
(1,'John Smith'),
(2,'Alice Johnson'),
(3,'Phillip Black'),
(4,'Sarah Goodwell'),
(5,'Ian Hunter')
insert into #users_badges
values
(1,1,1),
(2,1,2),
(3,1,3),
(4,1,4),
(5,2,1),
(6,2,2),
(7,2,4),
(8,3,5),
(9,4,1),
(10,4,2)
我认为这就是您正在寻找的结果(在这里,特别是查看 user_id
为 1 的用户 - John Smith):
select
b.*,
case when ub.id is not null then 'Earned' else null end as badgeStatus
from #badges b
left join #users_badges ub on b.badge_id = ub.badge_id and ub.[user_id] = 1
这列出了所有徽章并显示约翰获得了哪些徽章:
/------------------------------------------------------------------------|--------\
| id | name | description | status |
|----|--------------------|----------------------------------------------|--------|
| 1 | Starter Badge | It's your first time. | Earned |
| 2 | Rookie Badge | You're just getting started. | Earned |
| 3 | Intermediate Badge | Now you're starting to get the hang of this. | NULL |
| 4 | Expert Badge | You are a master! | Earned |
\---------------------------------------------------------------------------------/
关于mysql - 要求给出正确的徽章并模糊其余的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52965100/