通过另一个表在MySQL中查找行

6

I have two tables:

game

`id`        INT(11)

游戏标签

`game`      INT(11)
`tag_id`    INT(11)

game_tags.game = game.id

我对MySQL不是很了解,我的问题是:我想找出具有一定数量的的游戏。因此,如果我有四个(3、5、7、11),我希望能够通过查看表来找到具有这四个标签的游戏。以下是我所说的一个示例:

伪MySQL代码:

SELECT *
FROM `games`
WHERE (search through game_tags table and find which rows have the same `game` field and all of the tag_id's that I need to search for)
LIMIT 0, 15

我知道我解释得很糟糕(无法准确表达我内心的想法),所以如果你有任何问题,只需留下评论即可。


这是一个关系除法问题。 - ypercubeᵀᴹ
1
查看此问题以了解10种以上实现您想要的方式:https://dev59.com/i2s05IYBdhLWcg3wPfcR - ypercubeᵀᴹ
4个回答

4
您可以使用group byhaving子句,结合Bassam的查询,确保您已经找到了给定游戏的所有四个ID。
select
    game.*
from game
    join game_tags on game.id = game_tags.game
where
    tag_id in (3, 5, 7, 11)
group by
    game.id
having 
    count(distinct tag_id) = 4;

请注意,这是因为having子句在聚合函数count(distinct...)运行后执行,而where子句没有这个信息。

不幸的是,我们不能这样做,按组排序会抱怨games.*,因为列不在聚合函数中。必须在子选择中完成。 - Bassam Mehanni
只有在游戏表中有附加列时才需要这样做。 OP指出游戏表只有1列:“id”。 即使如此,我认为mysql不会对此抱怨。 但是,如果确实存在问题,您是正确的,需要使用子选择。 - Adam Wagner
好的,游戏表有大约10列,但我只发布了我认为你在这个查询中需要的一列。 - Matt

3
SELECT games.*
FROM games
     INNER JOIN 
     (SELECT game, COUNT(DISTINCT tag_id) AS gameCnt
      FROM game_tags
      WHERE tag_id in (3, 5, 7, 11)
      GROUP BY game) t on games.id = game
WHERE gameCnt = 4

我认为这不完全正确,因为它会返回包含任何四个指定标签之一的条目,而 OP 要求的是“我想能够找到具有这四个标签的所有游戏”。 - Adriaan Stander
@AdamWagner 我移除了 distinct,这个查询中不需要它。 - Bassam Mehanni
如果查询中不再添加任何连接,并且在 game_tags.gamegame_tags.tag_id 上存在唯一/主键约束,则返回 True。 - Adam Wagner
你需要向你的game_tags表中添加一个唯一约束,以确保游戏和tag_id的组合不会重复超过一次。 - Bassam Mehanni
让我们在聊天中继续这个讨论。点击此处进入聊天室 - Bassam Mehanni
显示剩余7条评论

0

你可以进行四个内连接,并添加四个类似于

t1.tag_id=1 and t2.tag_id=2 and ....

的where条件,这样可以得到你想要的结果。但可能存在更好的性能方式。


0

是的,这是一种有趣的方法。 查询不好。但也可以这样做。只是为了好玩!

SELECT game, BIT_OR(pow(2,tag_id)) AS tags 
FROM game_tags 
GROUP BY game 
HAVING tags = pow(2,3) + pow(2,5) + pow(2,7) + pow(2,11);

如果 tag_id=37011 会发生什么? - ypercubeᵀᴹ

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接