1

我实际上并不需要以下查询,但我醒来时遇到了这个我无法弄清楚的“理论问题”。假设我有三个表:用户表、组表和 users_groups 表,它是多对多的。因此,如果一个用户属于组 1 和组 2,则每个用户将有两个不同的行。

现在,假设有很多组,例如,我如何专门选择同时属于组 2 和组 3 的用户?

我尝试了一些类似的东西,但它显示为空:

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

我想这假设两个组都在同一行,这显然是行不通的。我该怎么做?

编辑:两种变体怎么样:用户必须只在这两个组中,并且用户必须至少在这两个组中?

4

5 回答 5

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

只有在这两组中稍微复杂一些。你可以这样做:

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 回答
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 回答
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

用户必须只属于 grp 2 和 grp 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 回答
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 回答