Reputation: 227
I have a table with two columns, blog post ids and tag ids. A blog post can have several tags like it's a post about "New York" and "Soho". Let's say I want to find all the blog posts that have BOTH tag id 1 and 2, how do I do that?
blogPostToTags
=============================
id |tagId
-----------------------------
1 |1
1 |2
2 |1
3 |2
UPDATE:
I've tried the following:
SELECT id FROM blogPostToTags WHERE tagId = 1 AND tagId = 2
and
SELECT id FROM blogPostToTags WHERE tagId = 1 OR tagId = 2
neither work...
Upvotes: 0
Views: 345
Reputation: 55673
Something along the lines of this should work
SELECT * FROM items i
WHERE EXISTS (
SELECT NULL
FROM blogPostToTags tg
WHERE tg.tagID IN ({tag_comma_separated_values})
AND tg.itemID = i.id
GROUP BY tg.itemID
HAVING COUNT(tg.tagID) = {tag_count}
)
in your case
SELECT * FROM items i
WHERE EXISTS (
SELECT NULL
FROM blogPostToTags tg
WHERE tg.tagID IN (1,2)
AND tg.itemID = i.id
GROUP BY tg.itemID
HAVING COUNT(tg.tagID) = 2
)
Upvotes: 0
Reputation: 230551
Use double JOIN
.
SELECT id
FROM blogPosts p
INNER JOIN blogPostToTags pt1 ON pt1.id = p.id
INNER JOIN blogPostToTags pt2 ON pt2.id = p.id
WHERE pt1.tagId = 1 AND pt2.tagId = 2;
Upvotes: 2
Reputation: 385405
SELECT `id`, COUNT(*) FROM
(SELECT `id` FROM `blogPostToTags` WHERE `tagId` = 1)
UNION
(SELECT `id` FROM `blogPostToTags` WHERE `tagId` = 2)
AS `_`
-- this temporary table contains an entry for each `id` when
-- the tag ID matches. I assume that `id`,`tagId` is a UNIQUE key.
-- COUNT(*) will be '2' for any `id` with both matches.
WHERE `n` = 2
GROUP BY `id`
I don't have an installation of MySQL handy so this is not tested, but it is instead a best-guess designed to send you on the way.
Upvotes: 0