0

我一直在以下方面苦苦挣扎。

我有 3 张桌子:players、players_clothes 和 teams_clothes。

players

id 用户 team_id
1 汤姆 4
2 机器人 5
3 鲍勃 4

所以汤姆和鲍勃都在同一个团队

players_clothes

id 衣服_id p_id
1 13 1
2 35 3
3 45 3

Bob 有服装物品 35 和 45,robo 没有。

teams_clothes

id 衣服 ID 团队 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 player_clothes.clothes_id 部分妨碍了

4

3 回答 3

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
)

基本上,我们找到他们团队中的所有 As,并且每个 A 加入他们穿的所有衣服,然后只返回如果我们在表 C 中找不到衣服在我们团队中的指示(这包括不存在)在 C 中并且存在但在 C 上的错误团队中)

于 2013-06-05T22:28:10.503 回答
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 的情况,这将表示外连接上没有关系匹配的情况(即该服装项目未被该用户的团队批准)。

于 2013-06-05T22:34:14.770 回答
1

不确定这对您来说是否为时已晚,但我会更改数据库模型本身以使这种情况首先变得不可能:

在此处输入图像描述

(为简洁起见,省略了“不重要”字段,包括代理键,例如 PLAYER_ID。)

请注意 TEAM_ID 如何通过标识关系从 TEAM 迁移到 PLAYER,然后再到 PLAYER_ARTICLE,它与通过 TEAM_ARTICLE 迁移的相同字段合并。由于 PLAYER_ARTICLE 表中只有一个物理 TEAM_ID 字段,因此您永远不能插入引用不同球队的行。

更抽象地说:这是一个菱形的依赖关系,其中 TEAM 位于顶部,PLAYER_ARTICLE 位于菱形的底部。底部的合并(通过使用识别关系实现)确保双方必须始终指向同一个顶部。


您的示例数据将像这样表示...

玩家:

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
于 2013-06-05T23:17:46.403 回答