2011-12-28 33 views
6

Tôi có hai bảng:MySQL tìm chèo qua bảng khác

trò chơi

`id`  INT(11) 

game_tags

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

game_tags.game = game.id

Tôi kinh khủng với MySQL, vì vậy đây là câu hỏi của tôi: Tôi muốn có thể tìm thấy những gì games có một số tiền nhất định là tag_id. Vì vậy, nếu tôi có bốn tag_id 's (3, 5, 7, 11), tôi muốn để có thể tìm thấy những gì trò chơi sẽ có tất cả bốn của những thẻ bằng cách xem xét thông qua các bảng game_tags. Dưới đây là một ví dụ về những gì tôi có nghĩa là:

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 

Tôi biết tôi đã giải thích khủng khiếp (không thể từ nó như thế nào trong tâm trí của tôi) này, vì vậy nếu bạn có thắc mắc gì, chỉ để lại một bình luận.

+0

Đây là vấn đề phân chia quan hệ. –

+1

Kiểm tra câu hỏi này trong hơn 10 cách để đạt được những gì bạn muốn: http://stackoverflow.com/questions/7364969/how-to-filter-sql-results-in-a-has-many-through-relation –

Trả lời

4

Bạn có thể sử dụng group byhaving khoản cùng với truy vấn Bassam để đảm bảo bạn đã tìm thấy tất cả bốn id cho một trò chơi nhất định.

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; 

Lưu ý rằng các công trình này vì mệnh đề having chạy sau khi tập hợp count(distinct ...) chạy, trong khi một điều khoản where không có thông tin này.

+0

thật không may chúng tôi sẽ không làm theo cách này, nhóm theo sẽ phàn nàn về trò chơi. * vì các cột không có trong hàm tổng hợp. nó sẽ phải được thực hiện trong một phụ chọn –

+0

chỉ khi có thêm cột trong bảng trò chơi. OP cho biết bảng trò chơi chỉ có 1 cột: 'id'. Mặc dù vậy, tôi không nghĩ rằng mysql phàn nàn về điều này. Nhưng, nếu có, bạn là chính xác, một lựa chọn phụ sẽ được yêu cầu. –

+0

Vâng, bảng trò chơi có 10 cột, nhưng tôi chỉ đăng một cột mà tôi nghĩ bạn sẽ cần cho truy vấn này. – 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 không nghĩ rằng điều này là khá chính xác, vì nó sẽ mang lại các mục có chứa bất kỳ của bốn thẻ được chỉ định, trong khi OP hỏi cho ** Tôi muốn để có thể tìm thấy những gì trò chơi sẽ có tất cả bốn ** –

+0

Cảm ơn, nhưng là người biết nói rằng, tôi cần để có thể tìm thấy những trò chơi có ** tất cả bốn ** – Matt

+0

@astander Làm thế nào về bây giờ? –

0

bạn có thể làm bốn bên tham gia và bổ sung bốn nơi mà điều kiện như

t1.tag_id = 1 và t2.tag_id = 2 và ....

này mang đến cho bạn những gì bạn muốn. nhưng có thể có cách thực hiện tốt hơn

0

Vâng, đây là cách tiếp cận hài hước. Truy vấn không hợp lệ. Nhưng cũng có thể được thực hiện như thế này. Chỉ để cho vui thôi!

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

Và điều gì sẽ xảy ra nếu 'tag_id = 37011'? –

Các vấn đề liên quan