Reputation: 39135
Sorry for the abysmal title - if someone wants to change it for something more self-explanatory, great - I'm not sure how to express the problem. Which is:
I have a table like so:
POST_ID (INT) TAG_NAME (VARCHAR)
1 'tag1'
1 'tag2'
1 'tag3'
2 'tag2'
2 'tag4'
....
What I want to do is count the number of POSTs which have both tag1 AND tag2.
I've messed about with GROUP BY and DISTINCT and COUNT but I can't construct a query which does the trick.
Any suggestions?
Edit: In pseudo sql, the query I want is:
SELECT DISTINCT(POST_ID) WHICH HAS TAG_NAME = 'tag1' AND TAG_NAME = 'tag2';
Thanks
Upvotes: 0
Views: 187
Reputation: 39773
Posts
.Join the table against itself:
SELECT * FROM Posts P1
JOIN Posts P2
ON P1.POST_ID = P2.POST_ID
WHERE P1.TAG_NAME = 'tag1'
AND P2.TAG_NAME = 'tag2'
Upvotes: 2
Reputation: 656
Try the following query:
SELECT COUNT(*) nb_posts FROM ( SELECT post_id, COUNT(*) nb_tags FROM table WHERE tag_name in ('tag1','tag2') GROUP BY post_id HAVING COUNT(*) = 2 ) t
Edit: based on Konerak answer, here is the query that handles the case when there are duplicated tag names for a given post:
SELECT DISTINCT t1.post_id FROM table t1 JOIN table t2 ON t1.post_id = t2.post_id AND t2.tag_name = 'tag2' WHERE t1.tag_name = 'tag1'
Upvotes: 0
Reputation: 85862
I'm just leaving this (untested) dependent subquery solution here for reference, even though it'll probably be horribly slow once you get to large data sets. Any solution that does the same thing using joins should be chosen over this.
Assuming you have a posts
table with an id
field, as well:
SELECT count(*) FROM posts WHERE EXISTS(SELECT NULL FROM posts_tags WHERE tag = 'tag1' AND post_id = posts.id) AND EXISTS(SELECT NULL FROM posts_tags WHERE tag = 'tag2' AND post_id = posts.id)
Upvotes: 0