This should be common enough and I'm looking for the "best" way to perform this in one SQL query (MySQL).
I have three tables, an items
table, a linker
table and a tags
table. Items can be tagged multiple times, so the linker is a simple foreign key linker table:
items | linker | tags
--------+---------+-------
item_id | item_id | tag_id
... | tag_id | name
--------+---------+-------
I can search items
for single tags easily, how would I go to search items that have 2 or more specific tags?
SELECT *, `tags`.`name`
FROM `items`
LEFT OUTER JOIN `linker` USING (`item_id`)
LEFT OUTER JOIN `tags` USING (`tag_id`)
WHERE `tags`.`name` = "tag-a"
How does a sane person perform search for 2 or more tags, an item must have ALL the tags, i.e. an AND
query?
Edit: What I have so far is the following, which works and doesn't seem to be slow, but looks crazy:
SELECT `items`.* FROM `items`
LEFT OUTER JOIN `linker` USING (`item_id`)
LEFT OUTER JOIN `tags` USING (`tag_id`)
WHERE (
`item_id` IN (SELECT item_id FROM linker LEFT JOIN tags USING (tag_id) WHERE name = "tag-a")
AND `item_id` IN (SELECT item_id FROM linker LEFT JOIN tags USING (tag_id) WHERE name = "tag-b")
AND `item_id` IN (SELECT item_id FROM linker LEFT JOIN tags USING (tag_id) WHERE name = "tag-c")
AND `item_stuff` = "whatever"
)