这会选择所有具有 任何 个标签(4、10、11)的帖子:
select distinct id, title from posts
where exists (
select * from posts_tags
where
post_id = id and
tag_id in (4, 10, 11))
或者你可以使用这个:
select distinct id, title from posts
join posts_tags on post_id = id
where tag_id in (4, 10, 11)
(两者都将以相同的方式进行优化)。
这会选择所有具有所有标签(4、10、11)的帖子:
select distinct id, title from posts
where not exists (
select * from posts_tags t1
where
t1.tag_id in (4, 10, 11) and
not exists (
select * from posts_tags as t2
where
t1.tag_id = t2.tag_id and
id = t2.post_id))
in 子句中的标签列表是动态变化的(在所有情况下)。
但是,最后一个查询并不是很快,所以你可以使用这样的代替:
create temporary table target_tags (tag_id int);
insert into target_tags values(4),(10),(11);
select id, title from posts
join posts_tags on post_id = id
join target_tags on target_tags.tag_id = posts_tags.tag_id
group by id, title
having count(*) = (select count(*) from target_tags);
drop table target_tags;
动态变化的部分现在在第二个语句(插入)中。