如何从两组中的多对多表中选择用户?

时间:2013-03-21 11:41:51

标签: mysql

我实际上并不需要以下查询,但我醒过这个理论问题"我很难搞清楚。假设我有三个表:用户表,组表和users_groups表,它是多对多的。因此,如果一个用户属于第1组和第2组,则每个用户将有两个不同的行。

现在,假设有很多组,我该如何具体选择属于第2组和第3组的用户?例如?

我沿着这些方向尝试了一些东西,但它显示为空:

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

我想这假设两个组都在同一行,这显然不会起作用。我该怎么做?

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

5 个答案:

答案 0 :(得分:2)

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

这当然假设{user_idgroup_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

答案 1 :(得分: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就足够了。

答案 2 :(得分:1)

  SELECT *, COUNT(*) FROM `users_groups` 
  WHERE group_id IN (2,3) 
  GROUP BY user_id HAVING COUNT(*) > 1

答案 3 :(得分:0)

用户必须仅属于第2组和第3组:

SELECT *, group_concat(group_id ASC) gui
FROM users_groups
GROUP BY user_id
HAVING gui="2,3"

答案 4 :(得分:0)

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