简体   繁体   English

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

[英]How to select a user from many-to-many table that is in two groups?

I don't actually need the following query, but I woke up with this "theoretical problem" that I'm having trouble figuring out. 我实际上不需要以下查询,但是我对这个“理论问题”一无所知,因为我很难弄清楚。 Say I have three tables: a users table, groups table, and users_groups table that is a many-to-many. 假设我有三个表:一个users表,groups表和users_groups表(多对多)。 So if one user belongs to group 1 and 2, there would be two different rows for each. 因此,如果一个用户属于组1和2,则每个用户都有两个不同的行。

Now, assuming that there are many groups, how do I select specifically the users that belong to both group 2 and 3, for example? 现在,假设有许多组,我该如何特别选择属于第2组和第3组的用户?

I tried something along these lines, but it showed empty: 我尝试了以下方法,但显示为空:

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

I guess that assumes that both groups are in the same row, which obviously won't work. 我猜这是假设两组都在同一行,这显然行不通。 How would I do this? 我该怎么做?

EDIT: How about both variants: where the user must ONLY be in these two groups, and the user must AT LEAST be in these two groups? 编辑:两个变体如何:用户必须仅在这两个组中,而用户必须至少在这两个组中?

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

This of course assumes that { user_id , group_id } is unique (and there are no other columns there to add additional rows to the count). 当然,这假设{ user_idgroup_id }是唯一的(并且没有其他列可向计数添加其他行)。 Otherwise you could ensure this explicitly: 否则,您可以明确确保:

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

Only in these two groups is slightly more complicated. 在这两组中稍微复杂一些。 You can either do: 您可以执行以下任一操作:

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

Or, 要么,

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

In groups 2 and 3, with more than 2 groups total: 在第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

The problem is called Relational Division . 这个问题叫做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 was used in the following query if a unique constraint on Name isn't enforce for every user, otherwise HAVING COUNT(*) = 2 will suffice. 如果不是每个用户都没有对Name实施唯一约束,则在以下查询中使用DISTINCT ,否则HAVING COUNT(*) = 2就足够了。

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

User must ONLY belong to grp 2 and grp 3: 用户只能属于grp 2和grp 3:

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

SELECT user_id FROM(从* group_id = 2的users_groups中选择*)grp 1,(从group_id = 3的users_groups中*选择*)grp2其中grp1.user_id = grp2.user_id

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM