MySQL查询表过滤问题

时间:2013-06-05 22:24:45

标签: mysql sql

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

我有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部分会妨碍

3 个答案:

答案 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)

不确定这对你来说是否为时已晚,但我首先要更改数据库模型以使这种情况无法实现:

enter image description here

(" 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