创建用户到组的映射,并根据用户组合获取组

时间:2016-04-15 13:47:51

标签: mysql database

我有一组用户和组。用户可以是一个或多个组的一部分,组可以有一个或多个用户。所以我得到了user_groups的联接表。

有没有办法根据用户的确切组合找出群组的名称?如果我为此设置的结构执行正确,我不是肯定的,这是两个例子:

ID为1(Jeff)的用户是两个组的一部分,如user_groups表所示。对于ID为2的一个群组,他是唯一的成员。对于另一组身份证4,他是两个成员之一。

我希望能够构建一个查询,如果我只有他的ID,我会知道组名是GP-B,因为那是映射。如果我有用户ID 14,则会映射到群组4,因此我知道群组名称是GP-D。

SELECT id, name FROM users;

1, Jeff
2, John
3, Mary
4, Jen
5, Mike

SELECT id, name FROM groups;

1, GP-A
2, GP-B
3, GP-C
4, GP-D

SELECT user_id, group_id FROM user_groups;

1, 2
1, 4
2, 3
4, 1
4, 4

到目前为止,我能提出的最佳查询是:

SELECT groups.name 
FROM user_groups
LEFT JOIN groups
    ON groups.id = user_groups.group_id
WHERE user_id IN (1,4)
GROUP BY group_id
HAVING COUNT(*) = 2;

这似乎有效。但是,如果我只做了一个用户:

SELECT groups.name 
FROM user_groups
LEFT JOIN groups
    ON groups.id = user_groups.group_id
WHERE user_id IN (1)
GROUP BY group_id
HAVING COUNT(*) = 1;

它最终会拉动他所属的两个群体,所以我的查询不正确。

1 个答案:

答案 0 :(得分:1)

You just need to move the WHERE expression - user_id IN (1) - in the JOIN condition:

SELECT groups.name 
FROM user_groups
LEFT JOIN groups
    ON groups.id = user_groups.group_id AND user_id IN (1)
GROUP BY group_id
HAVING COUNT(*) = 1 AND groups.name IS NOT NULL;

(and set a filter in the HAVING clause so that you will exclude NULL groups - those that didn't match)

This way you will get all rows from user_groups and then you will be able to make sure that the count will get the exact number of records that you inputted.

In your initial query, the WHERE clause filters out some rows so you can't actually correctly count how many members are in each group (because you exclude those that don't match your filter).