select image_id from tags
where tag='castle' and image_id in (
select image_id from tags
where tag='moat' and image_id in (
select image_id from tags
where tag != 'ducks'
)
)
Large nested queries will present their own problems, but for small numbers of tags you should be OK. Also you could create an index of how frequently a tag occurs so that you can structure you nested query with least-frequent tag occurring first (the innermost query) for better performance. And of course your tag table should be indexed.tag IN ('moat', 'castle'), it can't also have tag = 'duck', so if the first part of the WHERE clause evaluates as true, the second part does, too.SELECT image_id FROM tags a WHERE
EXISTS (SELECT 1 FROM tags b WHERE b.image_id = a.image_id AND tag = 'moat')
AND EXISTS (SELECT 1 FROM tags b WHERE b.image_id = a.image_id AND tag = 'castle')
AND NOT EXISTS (SELECT 1 FROM tags b WHERE b.image_id = a.image_id AND tag = 'duck')SELECT image_id FROM tags WHERE tag = 'castle' AND image_id IN (SELECT image_id FROM tags WHERE tag = 'moat') AND image_id NOT IN (SELECT image_id FROM tags WHERE tag = 'ducks')SELECT image_id FROM tags WHERE tags LIKE '% castle %' AND tags LIKE '% moat %' AND tags NOT LIKE '% ducks %'
SELECT * FROM tags WHERE (tag='castle' OR tag='moat') AND tag!='ducks';
posted by grumblebee at 2:01 PM on September 19, 2006