badge_id
表中的badge_requirements
存在所有任务,我想查询徽章表以获取徽章。
在下面的情况下,将返回徽章,因为对于badge_id = 1
,所有任务都存在。
但是,例如,如果finished_missions
表中的一条记录不存在,则不会返回徽章。
user_id
将从应用程序提供。
table badges
+----+------+-------+
| id | name | image |
+----+------+-------+
| 1 | OHYE | path |
+----+------+-------+
PK(id)
table badge_requirements
+------------+----------+
| mission_id | badge_id |
+------------+----------+
| 3 | 1 |
+------------+----------+
| 5 | 1 |
+------------+----------+
UNIQUE(mission_id, badge_id)
FK(mission_id, missions.id)
FK(badge_id, badges.id)
table finished_missions
+----+---------+------------+
| id | user_id | mission_id |
+----+---------+------------+
| 3 | 221 | 3 | // if any of these record doesn't exist
+----+---------+------------+
| 5 | 221 | 5 | // the badge associated with this mission would not be returned
+----+---------+------------+
PK(id)
FK(user_id, users.id)
FK(mission_id, missions.id)
修改
将missions
表格更改为finished_missions
以提高可读性。
用户ID和任务ID仅引用用户和任务表。
编辑2 我从答案中得到了这个尝试:
SELECT * FROM badges b
INNER JOIN finished_missions fm ON (fm.user_id = 221)
INNER JOIN badge_requirements br ON (br.mission_id = fm.mission_id AND br.badge_id = b.id)
但即使我在finished_missions
表中只有一条记录,它仍会返回徽章。
答案 0 :(得分:1)
一种方法是计数方法:
badge_id
这将返回badges
。如果您需要更多信息,请加入in
表或使用badge_requirements
。
并且,如果count(*)
中没有重复项,则使用count(distinct)
代替{{1}}。
答案 1 :(得分:0)
select * from badges b
inner join mission m on (m.user_id=@userid)
inner join badge_requirements br on (br.mission_id=m.mission_id and br.badge_id=b.id)
其中@userid是SQL参数。
答案 2 :(得分:0)
select user_id, badge_id
from
badge_requirements br on b.id = br.badge_id
inner join
missions m on m.id = br.mission_id
group by user_id, badge_id
having
array_agg(distinct br.mission_id order by br.mission_id) =
array_agg(distinct m.id order by m.id)
where user_id = 221
答案 3 :(得分:0)
有很多方法。这应该是一个:
SELECT badge_id
FROM ( -- count missions per badge for the given user
SELECT br.badge_id, count(*) AS ct
FROM finished_missions fm
JOIN badge_requirements br USING (mission_id)
WHERE fm.user_id = 221
GROUP BY 1
) u -- count missions per badge total
JOIN (
SELECT br.badge_id, count(*) AS ct
FROM badge_requirements
) b USING (badge_id, ct) -- only badges with the full count of missions
除了您声明的约束之外,UNIQUE(user, mission_id)
上还应该有一个finished_missions
来禁止重复输入。或者您必须在第一个子查询中使用count(DISTINCT mission_id) AS ct
,因此您可以依赖计数。
并且UNIQUE(mission_id, badge_id)
应该是PK - 或者为这两列添加NOT NULL
约束。