MySQL:特定の値を持つグループを選択する方法は?
質問
そのようなテーブルがあるとします:
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)
フィールド名はかなり自明です。選択したい post_id
1と3の両方を持つs tag_id
S、この例ではそれだけです 1
. 。私はようなものを考えましたSELECT post_id FROM tags GROUP BY post_id HAVING ...
リストしたい後 tag_id
このグループに存在するs。それ、どうやったら出来るの?
解決
一意の制約がない場合は、次のことを試してください。
SELECT post_id
FROM tags
WHERE tag_id = 1 OR tag_id = 3
GROUP BY post_id
HAVING count(DISTINCT tag_id) = 2;
またはこれを使用します HAVING
節、2つだけを検出しようとしている場合 tag_id
値:
HAVING MIN(tag_id) <> MAX(tag_id)
post_idとtag_idの両方が一意の制約を持っている場合、これも機能するはずです。
SELECT post_id
FROM tags
WHERE tag_id = 1 OR tag_id = 3
GROUP BY post_id
HAVING count(*) = 2;
他のヒント
セルフ参加を試すことができます(n tag_id-> n結合)が、おそらく速くはありません
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
私はあなたの他のテーブルについていくつかの仮定をしました。 (つまり、私が電話した投稿のテーブルがあること posts
そして、私が呼んだPKとしてtag_idを持つもの tag_table
投稿/タグテーブルでnameclashを避けるために、私はあなたがすでに電話するのを見ることができます tags
)
リストにタグが存在しない場所{1,3}には、対応するpost_id/tag_idと一致するレコードが存在しないため、以下のようにダブルNot存在するコンストラクトを使用できます。
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)
)
別の代替アプローチは、グループを使用してカウントすることです。 この問題へのアプローチのレビューはこちらです.
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
質問の2番目の部分にgroup_concat()を使用してください
SELECT post_id,
GROUP_CONCAT(tag_id ORDER BY tag_id ASC SEPARATOR ',')
FROM tags
どうですか
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)
);
@キーパーのソリューションのバージョン
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
所属していません StackOverflow