long time lurker here, been using the advice from this site for years, and now I have a question that I can't find an answer to - I'm sure the solution is simple though!
I'm setting up a tagging system for music tracks. I have three tables
Tracks
---------------
| id | name |
---------------
| 1 | Track1 |
| 2 | Track2 |
---------------
Taglinks
--------------------------
| id | tag_id | track_id |
--------------------------
| 1 | 1 | 1 |
| 2 | 2 | 1 |
| 3 | 2 | 2 |
--------------------------
Tags
-------------------------
| id | tag | type |
-------------------------
| 1 | acoustic | genre |
| 2 | anger | mood |
-------------------------
I want to be able to get the track name of tracks which have, for example, tag:acoustic, type:genre AND tag:anger, type:mood. So in this case I want track 1 as this has both tags.
The current query I have is
SELECT tracks.name
FROM tracks
JOIN taglinks ON tracks.id=taglinks.track_id
JOIN tags ON (tags.type='genre' AND tags.tag='acoustic') AND (tags.type='mood' AND tags.tag='anger')
WHERE taglinks.tag_id=tags.id;
This returns nothing, if I remove the AND section in the second JOIN then I get all tracks tagged acoustic as expected and if I change it to an OR I get both tracks, again as expected.
How do I do an AND though and return only those tracks that have both those tag and type?
Thanks in advance :D
EDIT:
Just to clarify what I am after. I want to be able to retrieve tracks that have both Acoustic and Anger as tags, but only when those tags also match the given type.
This is because later I might have a tag called jazz with type genre, and a tag called jazz with type style and I need to be able to make sure I am selecting by the correct type of tag as well as the tag itself.
Here's the link to the sqlfiddle I'm working with - http://sqlfiddle.com/#!2/aad82/3.
Gilles's answer seems to be a good solution so far!