我正试图绕过这个查询,但其中一条记录仍然不断弹出。总之,我的目的是在左侧显示组成员,并在电话簿中显示右侧组中不的名称。这样,用户就可以选择它们并将它们添加到组中。
user_id firstname group_id grpname
------- --------- -------- ----------
1 Luker 3 Abc
2 John 1 Some Group
3 Sam 2 Awesome Group
4 Mitch 1 Some Group
4 Mitch 2 Awesome Group
5 Rocky (NULL) (NULL)
6 Pops (NULL) (NULL)
唯一的事情是,如果其中一个用户是多个组(user_id 4)的一部分,则他们的名字根本不应该显示在电话簿中,因为它已经被放置在现有成员列表中。
-- Query for group_id 2
SELECT user.id user_id, user.firstname, grp.id group_id, grp.grpname FROM agi_user user
LEFT JOIN agi_group_user gu ON user.id = gu.user_id
LEFT JOIN agi_groups grp ON gu.group_id = grp.id
WHERE grp.id IS NULL OR grp.id != 2
GROUP BY user.id
但出于某种原因,用户 Mitch 仍然不断弹出。
user_id firstname group_id grpname
------- --------- -------- ----------
1 Luker 3 Abc
2 John 1 Some Group
4 Mitch 1 Some Group
5 Rocky (NULL) (NULL)
6 Paps (NULL) (NULL)
编辑:: 我需要的输出是
user_id firstname group_id grpname
------- --------- -------- ----------
1 Luker 3 Abc
2 John 1 Some Group
5 Rocky (NULL) (NULL)
6 Paps (NULL) (NULL)
基本上,我希望所有用户都不是该组的一部分,包括NULL。但是由于一个用户是多个组的一部分,因此她的记录仍然会出现,因为其他组可能有一个group_id为3或4(或除了2之外的任何其他组)。
答案 0 :(得分:3)
您可以使用NOT EXIST
检查组2和给定用户是否没有组/用户行:
SELECT
user.id user_id,
user.firstname,
grp.id group_id,
grp.grpname
FROM
agi_user user
LEFT JOIN agi_group_user gu ON user.id = gu.user_id
LEFT JOIN agi_groups grp ON gu.group_id = grp.id
WHERE
NOT EXISTS (
SELECT 'x' FROM agi_group_user x
WHERE
x.user_id = user.user_id and
x.group_id = 2)
GROUP BY
user.id
请注意,如果用户不在第2组中,但是在另外两个组中,则他将在此结果中显示1次,并且仅返回其所在的组中的一个。要解决此问题,您可以将grp.id添加到GROUP BY
子句中,也可以使用GROUP_CONCAT
在单个字段中返回组名列表。
或者,这也应该工作,并且在MySQL中它甚至可能表现得更好,因为它在子查询中很糟糕。我个人认为,在语义上不太清楚发生了什么。
它第二次连接用户/组表,但将group_id(2)添加到连接。如果没有为此表返回任何行,则该用户不在第2组中。有关GROUP_CONCAT
的注释也适用于此查询。
SELECT
user.id user_id,
user.firstname,
grp.id group_id,
grp.grpname
FROM
agi_user user
LEFT JOIN agi_group_user gu ON user.id = gu.user_id
LEFT JOIN agi_groups grp ON gu.group_id = grp.id
LEFT JOIN agi_group_user x ON user.id = x.user_id and x.group_id = 2
WHERE
x.group_id IS NULL
GROUP BY
user.id
答案 1 :(得分:3)
如果我理解正确,您需要这样:“所有不属于第2组的用户”
这称为反半连接(或者只是反连接),可以使用LEFT JOIN /IS NULL
查询完成:
SELECT u.id user_id, u.firstname
FROM agi_user AS u
LEFT JOIN agi_group_user AS gu
ON u.id = gu.user_id
AND gu.group_id = 2
WHERE gu.group_id IS NULL ;
或使用NOT EXISTS
子查询:
SELECT u.id user_id, u.firstname
FROM agi_user AS u
WHERE NOT EXISTS
( SELECT 1
FROM JOIN agi_group_user AS gu
WHERE u.id = gu.user_id
AND gu.group_id = 2
) ;