我一直在为以下方面苦苦挣扎。
我有3个桌子:玩家,玩家服装和球队服装。
表players
:
id user team_id 1 tom 4 2 robo 5 3 bob 4
所以tom和bob都在同一个团队中
表players_clothes
:
id clothes_id p_id 1 13 1 2 35 3 3 45 3鲍勃有服装第35和45条,机器人没有。
表teams_clothes
:
id clothes_id team_id 1 35 4 2 45 4 3 55 4 4 65 5
这表明哪些团队有权获得哪些服装。问题是:汤姆穿着一件不属于他的团队的衣服......让我们假设这是非法的。
我无法弄清楚如何抓住所有为特定团队穿着非法服装的人。
SELECT pc.clothes_id FROM players AS p
JOIN players_clothes AS pc
ON p.id = pc.p_id
AND p.team_id = 4 GROUP BY pc.clothes_id
(我通过players_clothes.clothes_id分组,因为信不信由你,可以为两名球员分配同一件衣服)
我认为这会产生以下集合(13,35,45)
现在我想检查一下团队4拥有的实际衣服。
SELECT clothes_id FROM teams_clothes WHERE team_id = 4 and this return (35, 45, 55)
如何创建查询以便返回(13)?我尝试过像NOT EXISTS IN这样的东西,但我认为GROUP BY players_clothes.clothes_id部分会妨碍
答案 0 :(得分:2)
我建议
select * from A where team_id = $team_id join B on B.a_id = A.id
where not exists
(
select 1 from C where C.clothes_id = B.clothes_id and team_id = $team_id
)
基本上,我们发现他们的团队和每个A的所有人都加入他们所穿的所有衣服,然后只返回行,如果我们在表C中找不到服装在我们团队中的指示(这C中不存在的覆盖,但存在于C)的错误团队中
答案 1 :(得分:2)
这应该可以解决问题:
SELECT b.a_id, b.clothes_id
FROM
b INNER JOIN a
ON b.a_id = a.id
LEFT OUTER JOIN c
ON a.team_id = c.team_id
WHERE
c.clothes_id = NULL
我们的想法是在表A / B与表C的组合上进行外连接。然后只查找c.clothes_id为NULL的情况,这将代表那些没有关系匹配的情况。外部联接(即衣服项目未获得该用户团队的批准)。
答案 2 :(得分:1)
不确定这对你来说是否为时已晚,但我首先要更改数据库模型以使这种情况无法实现:
(" Unimportant"字段为简洁省略,包括代理键,如PLAYER_ID。)
请注意TEAM_ID如何通过识别关系从TEAM迁移到PLAYER,然后迁移到PLAYER_ARTICLE,其中合并与通过TEAM_ARTICLE迁移的相同字段。由于PLAYER_ARTICLE表中只有一个物理TEAM_ID字段,因此您永远不能插入引用不同团队的行。
用更抽象的术语来表达:这是一个菱形依赖关系,其中TEAM位于顶部,PLAYER_ARTICLE位于钻石底部。底部的合并(通过使用识别关系启用)确保方必须始终指向相同的顶部。
您的示例数据将如下所示......
<强> PLAYER:强>
TEAM_ID PLAYER_NO
4 1 -- Tom
5 1 -- Robo
4 2 -- Bob
<强> TEAM_ATRICLE:强>
TEAM_ID ARTICLE_ID
4 35
4 45
4 55
5 65
<强> PLAYER_ARTICLE:强>
TEAM_ID PLAYER_NO ATRICLE_ID
4 1 13 -- Tom: this is impossible (FK violation).
4 2 35 -- Bob
4 2 45 -- Bob