Suppose I have the following three tables expressing a relationship where posts are given tags (a many-to-many relationship):
create table posts (id integer, con
Should be able to do this use NOT EXISTS, e.g.,
select t1.post_id
from post_tags as t1
inner join post_tags as t2 on t2.post_id = t1.post_id
where
t1.tag = 'clever'
and t2.tag = 'interesting'
and not exists (
select *
from post_tags t3
where
t3.tag not in ('clever', 'interesting')
and t3.post_id = t1.post_id
)
This is an exact relational division problem.
In SQL Server a well performing method (assuming unique constraint on post_id,tag
) is
SELECT post_id
FROM post_tags
GROUP BY post_id
HAVING MIN(CASE
WHEN Keyword IN ( 'clever', 'interesting' ) THEN 1
ELSE 0
END) = 1
AND SUM(CASE
WHEN Keyword IN ( 'clever', 'interesting' ) THEN 1
ELSE 0
END) = 2
So I wouldn't rule out the idea of using GROUP_CONCAT
in the HAVING
instead.
HAVING GROUP_CONCAT(DISTINCT Keyword ORDER BY Keyword) = 'clever,interesting'