1

次のクエリは実際には必要ありませんが、この「理論上の問題」を理解するのに苦労していることに気づきました。users テーブル、groups テーブル、多対多の users_groups テーブルの 3 つのテーブルがあるとします。したがって、1 人のユーザーがグループ 1 と 2 に属している場合、それぞれに 2 つの異なる行が存在します。

さて、グループがたくさんあると仮定して、例えば、グループ 2 と 3 の両方に属するユーザーを具体的にどのように選択すればよいでしょうか?

これらの行に沿って何かを試しましたが、空でした:

SELECT * FROM `users_groups` GROUP BY user_id HAVING group_id = 2 AND group_id = 3

両方のグループが同じ行にあると仮定していると思いますが、これは明らかに機能しません。どうすればいいですか?

編集: 両方のバリアントはどうですか: ユーザーはこれら 2 つのグループにのみ存在する必要があり、ユーザーは少なくともこれら 2 つのグループに存在する必要がありますか?

4

5 に答える 5

2

問題は と呼ばれRelational Divisionます。

SELECT  a.ID, a.Name
FROM    users a
        INNER JOIN users_groups b
            ON a.ID = b.UserID
        INNER JOIN groups c
            ON b.group_ID = c.ID
WHERE   c.Name IN ('grp2', 'grp3')
GROUP   BY a.ID, a.Name
HAVING  COUNT(DISTINCT c.Name) = 2

DISTINCT一意の制約Nameがすべてのユーザーに適用されない場合、次のクエリで使用されました。それ以外の場合HAVING COUNT(*) = 2は十分です。

于 2013-03-21T11:45:31.490 に答える
2
SELECT *
FROM users_groups
GROUP BY user_id
WHERE group_id IN (2,3)
HAVING COUNT(1) = 2

もちろん、これは { user_id, group_id} が一意であることを前提としています (そして、カウントに追加の行を追加する他の列はありません)。それ以外の場合は、これを明示的に確認できます。

SELECT *
FROM users_groups
GROUP BY user_id
WHERE group_id IN (2,3)
HAVING COUNT(DISTINCT group_id) = 2

これらの 2 つのグループでのみ、少し複雑になります。次のいずれかを実行できます。

SELECT *
FROM users_groups g1
GROUP BY user_id
WHERE group_id IN (2,3)
AND NOT EXISTS
(
    SELECT 1
    FROM users_groups AS g2
    WHERE g2.user_id = g1.user_id
    AND group_id NOT IN (2,3)
)
HAVING COUNT(1) = 2

または、

SELECT *
FROM users_groups g1
GROUP BY user_id
HAVING COUNT(1) = 2
AND SUM(CASE WHEN group_id IN (2,3) THEN 1 ELSE 0 END) = 2

グループ 2 と 3 で合計 2 つ以上のグループがある場合:

SELECT *
FROM users_groups g1
GROUP BY user_id
HAVING SUM(CASE WHEN group_id IN (2,3) THEN 1 ELSE 0 END) = 2
AND COUNT(1) > 2
于 2013-03-21T11:43:32.887 に答える
1
  SELECT *, COUNT(*) FROM `users_groups` 
  WHERE group_id IN (2,3) 
  GROUP BY user_id HAVING COUNT(*) > 1
于 2013-03-21T11:43:39.643 に答える
0

SELECT user_id FROM (select * from users_groups where group_id = 2) grp 1, (select * from users_groups where group_id = 3) grp2 where grp1.user_id = grp2.user_id

于 2013-03-21T12:07:18.533 に答える
0

ユーザーはグループ 2 とグループ 3 にのみ属している必要があります:

SELECT *, group_concat(group_id ASC) gui
FROM users_groups
GROUP BY user_id
HAVING gui="2,3"
于 2013-03-21T11:50:57.787 に答える