Assume I have two SQL tables. One that represents a post with columns (post_id, post_content) and one that represents tags associated to a post with columns (post_id, tag_text).
What do I have to do if I want to retrieve the post which have TAG1
and TAG2
, since a request like
SELECT post_id FROM posts JOIN tags ON posts.post_id=tags.post_id
WHERE tag_text ='TAG1' AND tag_text='TAG2'
obviously does not do what I want?
EDIT: Note that the number of AND is dynamically generated in my examples. That is, it is not sufficient to double the inner join.
Here is the query:
SELECT * FROM posts p
WHERE
EXISTS ( SELECT 1 FROM tags t1 WHERE t1.post_id = p.post_id AND t1.tag_text='TAG1')
AND
EXISTS ( SELECT 1 FROM tags t2 WHERE t2.post_id = p.post_id AND t2.tag_text='TAG2')
You can generate dynamic query (Dynamic EXISTS for each tag) if number of tag texts is not fixed.
select p.post_id
from posts p
join tags t ON p.post_id=t.post_id
where t.tag_text in ( 'TAG1', 'TAG2')
group by p.post_id
having count(distinct t.tag_text) = 2;
This will however also return posts that have more than those two tags (eg tag1, tag2 and tag3). If you don't want that, you need to limit the result to those posts which have exactly two tags:
select p.post_id
from posts p
join tags t ON p.post_id=t.post_id
where t.tag_text in ( 'TAG1', 'TAG2')
group by p.post_id
having count(distinct t.tag_text) = 2
and count(distinct t.tag_text) = (select count(*)
from tags t2
where t2.post_id = t.post_id);
Btw: if you only want the post_id
you don't need the join at all:
select post_id
from tags
where tag_text in ( 'TAG1', 'TAG2')
group by post_id
having count(distinct tag_text) = 2;
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.