3

为 SQL 问题命名很难!如果您能想到如何更好地描述这一点,请随意更改它!

我有一个非常典型的设置:3 个表、usersgroupsgroup_members

这是一个 SQL 小提琴:http ://sqlfiddle.com/#!2/23712/1

我想知道哪些组是哪些用户。

所以,我正在运行:

SELECT u.id, u.firstname, u.lastname,
GROUP_CONCAT(m.group_id) as groups
FROM group_members m, users u
WHERE m.user_id = u.id
GROUP BY id
ORDER BY u.lastname ASC

这很酷,并向我显示用户名和他们所在的组。

我的问题是不属于任何组的用户不会出现,因为当然 WHERE 位与他们不匹配。

我怎样才能返回不属于任何组的用户?(在上面的 SQL Fiddle 中,我想要 Zack Jones 的另一行,表明他要么在第 0 组,要么为 NULL 或其他什么!)

4

6 回答 6

4

您应该在不确定匹配是否可用的表上使用 LEFT JOIN。在您的情况下,您应该左加入 group_members 表。

SELECT u.id,
       u.firstname,
       u.lastname,
       GROUP_CONCAT(m.group_id) AS groups
FROM   users
       LEFT JOIN group_members
              ON users.id = group_members.user_id
GROUP  BY id
ORDER  BY users.lastname ASC
于 2012-08-29T14:46:18.570 回答
4
SELECT
    u.id, u.firstname, u.lastname, GROUP_CONCAT(m.group_id) as groups
FROM
    users u
    LEFT JOIN
    group_members m ON  m.user_id = u.id
GROUP BY u.id, u.firstname, u.lastname
ORDER BY u.lastname ASC

使用显式 JOIN,而不是隐含的 WHERE JOIN。在这种情况下,使用 LEFT OUTER JOIN

此外,不要依赖 MySQL GROUP BY 扩展:它们并不总是按预期工作

于 2012-08-29T14:46:44.353 回答
4

您将希望在以下位置使用LEFT JOIN您的users桌子group_members

SELECT u.id, 
  u.firstname, 
  u.lastname, 
  GROUP_CONCAT(m.group_id) as groups 
FROM users u
LEFT JOIN group_members m 
  ON u.id = m.user_id
GROUP BY u.id, u.firstname, 
  u.lastname
ORDER BY u.lastname ASC

SQL Fiddle with Demo

或者你RIGHT JOIN group_members可以users

SELECT u.id, 
  u.firstname, 
  u.lastname, 
  GROUP_CONCAT(m.group_id) as groups 
FROM group_members m
RIGHT JOIN users u
  ON m.user_id = u.id 
GROUP BY id, u.firstname, 
  u.lastname
ORDER BY u.lastname ASC

SQL Fiddle with Demo

于 2012-08-29T14:49:15.233 回答
1
SELECT u.id, u.firstname, u.lastname,
GROUP_CONCAT(m.group_id) as groups
FROM users u
LEFT JOIN group_members m on m.user_id = u.id
GROUP BY u.id
ORDER BY u.lastname ASC
于 2012-08-29T14:47:14.047 回答
1

外连接在这些情况下很有用。我已经交换了 users 和 group_members m 以进行左外连接。您还应该考虑避免在 where 子句中执行 JOIN。

SELECT u.id, u.firstname, u.lastname, GROUP_CONCAT(m.group_id) as groups 
FROM users u LEFT OUTER JOIN group_members m 
ON m.user_id = u.id 
GROUP BY id 
ORDER BY u.lastname ASC
于 2012-08-29T14:47:38.897 回答
1
SELECT 
        u.id, 
        u.firstname, 
        u.lastname,
        m.groups
FROM users u
LEFT JOIN (
            SELECT  user_id,
                    GROUP_CONCAT(m.group_id) as groups  
            FROM group_members
           ) as m on m.user_id = u.id
WHERE m.user_id = u.id
GROUP BY id
ORDER BY u.lastname ASC

在您的查询中,您使用的是笛卡尔积。避免使用你的方法,因为它会带来太多不想要的结果,而是使用连接更快,因为它们是

于 2012-08-29T14:51:41.563 回答