2011-12-28 13 views
6

Tengo dos tablas:MySQL encontrar la fila a través de otra mesa

juego

`id`  INT(11) 

game_tags

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

game_tags.game = game.id

Soy horrible con MySQL, así que aquí está mi pregunta: Quiero encontrar lo que games tiene una cierta cantidad de tag_id 's. Entonces, si tengo cuatro tag_id (3, 5, 7, 11), quiero ser capaz de encontrar qué juegos tendrán las cuatro de esas etiquetas mirando a través de la tabla game_tags. Aquí está un ejemplo de lo que quiero decir:

pseudo-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 

Sé que he explicado este horrible (no podía palabra como si fuera en mi mente), por lo que si usted tiene alguna pregunta, sólo Deja un comentario.

+0

Este es un problema de división relacional. –

+1

Consulte esta pregunta para obtener más de 10 formas de lograr lo que desea: http://stackoverflow.com/questions/7364969/how-to-filter-sql-results-in-a-has- many-through-relation –

Respuesta

4

Puede utilizar group by y having cláusulas junto con la pregunta de Bassam para asegurar que haya encontrado todos los identificadores de cuatro para un juego determinado.

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; 

Tenga en cuenta que esto funciona porque la cláusula having se ejecuta después de la agregación count(distinct ...) carreras, mientras que una cláusula where no tiene esta información.

+0

lamentablemente no lo haremos de esta manera, agrupemos se quejará de los juegos. * porque las columnas no están en una función agregada. Tendrá que hacerse en un sub seleccionar –

+0

solo si hay columnas adicionales en la mesa de juego. OP declaró que la mesa de juego solo tiene 1 columna: 'id'. Aun así, no creo que mysql se queje de esto. Pero, si lo hace, está en lo correcto, se requeriría una selección secundaria. –

+0

Bueno, la mesa de juego tiene como 10 columnas, pero solo publiqué la columna que pensé necesitaría para esta consulta. – 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 no creo que esto sea del todo correcto, ya que traerá entradas que contienen cualquiera de las cuatro etiquetas especificadas, mientras que el OP pidió ** Quiero poder encontrar qué juegos tendrán los cuatro ** –

+0

Gracias, pero como espectador dijo, necesito poder encontrar qué juegos tienen ** los cuatro ** – Matt

+0

@astander ¿Y ahora? –

0

que puede hacer cuatro combinaciones internas y añadir cuatro en perfectas condiciones

t1.tag_id = 1 y = 2 y t2.tag_id ....

esto le da lo que quiere. pero puede haber una mejor forma de ejecución

0

Sí, este es un enfoque divertido. Mala consulta. Pero también se puede hacer así. ¡Solo por diversión!

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

¿Y qué pasa si 'tag_id = 37011'? –

Cuestiones relacionadas