Mysql: how to select groups having specific values?

Let's say that there is such a table:

mysql> SELECT * FROM tags;
+---------+--------+
| post_id | tag_id |
+---------+--------+
|       1 |      2 |
|       1 |      3 |
|       1 |      1 |
|       2 |      1 |
|       2 |      2 |
+---------+--------+
5 rows in set (0.00 sec)

Field names are pretty straightforward. I want to choose post_idwhich have both 1 and 3 tag_ids, so in this example it is only 1. I thought of something like SELECT post_id FROM tags GROUP BY post_id HAVING ...After I want to list tag_idwho are in this group. How to do it?

+6
source share
6 answers

If there are no unique restrictions, try:

SELECT post_id 
FROM tags 
WHERE tag_id = 1 OR tag_id = 3 
GROUP BY post_id 
HAVING count(DISTINCT tag_id) = 2;

Or use this sentence HAVINGif you are trying to detect only two values tag_id:

HAVING MIN(tag_id) <> MAX(tag_id)

If post_id and tag_id have a unique constraint, this should also work:

SELECT post_id 
FROM tags 
WHERE tag_id = 1 OR tag_id = 3 
GROUP BY post_id 
HAVING count(*) = 2;
+7

(N tag_id → N join), , ,

SELECT t1.post_id 
FROM tags t1 INNER JOIN tags t2 ON t1.post_id = t2.post_id 
WHERE t1.tag_id = 1 AND t2.tag_id = 3
+2

. (.. , posts, tag_id PK, tag_table, nameclash posts/tags, , tags)

, {1,3}, post_id/tag_id, NOT EXISTS, .

SELECT post_id
FROM posts p
WHERE NOT EXISTS 
    (SELECT * FROM tag_table tt
    WHERE tag_id IN (1,3)
    AND NOT EXISTS
        (SELECT * FROM tags t
        WHERE t.tag_id = tt.tag_id  and
        p.post_id = t.post_id)        
    )

Group By Count. .

+1
SELECT post_id
  FROM ( SELECT post_id,
                count(tag_id) AS counter
           FROM tags
          WHERE tag_id IN (1,3)
          GROUP BY post_id
       )
 WHERE counter = 2

GROUP_CONCAT()

SELECT post_id,
       GROUP_CONCAT(tag_id ORDER BY tag_id ASC SEPARATOR ',')
  FROM tags
+1

SELECT * 
FROM tags 
WHERE post_id in 
  (SELECT post_id AS pid 
   FROM tags 
   WHERE 1 IN (SELECT tag_id FROM tags WHERE post_id = pid) 
   AND 3 IN (SELECT tag_id FROM tags WHERE post_id = pid)
  );
0
source

WHERE version of @Keeper solution

SELECT DISTINCT t1.post_id 
FROM tags t1, tags t2
WHERE 
  t1.post_id = t2.post_id  AND 
  t1.tag_id = 1 AND t2.tag_id = 3
0
source

All Articles