2011-12-28 3 views
6

У меня есть две таблицы:MySQL найти грести через другую таблицу

игра

`id`  INT(11) 

game_tags

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

game_tags.game = game.id

Я ужасен с MySQL, так что вот мой вопрос: я хочу, чтобы найти то, что games есть определенное количество tag_id. Поэтому, если у меня есть четыре tag_id (3, 5, 7, 11), я хочу, чтобы найти, какие игры будут иметь все четыре из этих тегов, просматривая таблицу game_tags. Вот пример того, что я имею в виду:

псевдо-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 

Я знаю, что я объяснил это ужасное (не могли слово это, как и в моем уме), так что если у вас есть какие-либо вопросы, просто Оставить комментарий.

+0

Это проблема разделения отношений. –

+1

Проверьте этот вопрос на более чем 10 способов достижения желаемого результата: http://stackoverflow.com/questions/7364969/how-to-filter-sql-results-in-a-has-many-through-relation –

ответ

4

Вы можете использовать group by и having положения вместе с запросом Бассама, чтобы убедиться, что вы нашли все четыре идентификаторов для данной игры.

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 не имеет такой информации.

+0

К сожалению, мы не будем этого делать, будет жаловаться на игры. * потому что столбцы не имеют агрегатной функции. это нужно сделать в подблоке select –

+0

, только если в таблице игр есть дополнительные столбцы. OP заявила, что таблица игр содержит только 1 столбец: 'id'. Тем не менее, я не думаю, что mysql жалуется на это. Но, если это так, вы правы, потребуется дополнительный выбор. –

+0

Ну, таблица игр имеет 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 
+0

I не думаю, что это совершенно правильно, так как оно вернет записи, содержащие любой из четырех указанных тегов, тогда как OP попросил ** Я хочу, чтобы найти, какие игры будут иметь все четыре ** –

+0

Спасибо, но как наблюдатель сказал, мне нужно найти, какие игры есть ** все четыре ** – Matt

+0

@astander Как насчет сейчас? –

0

вы можете сделать четыре внутренних соединений и добавить четыре, где состояние как

t1.tag_id = 1 и t2.tag_id = 2 и ....

это дает вам то, что вы хотите. но может быть более эффективный способ

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); 
+0

И что произойдет, если 'tag_id = 37011'? –

Смежные вопросы