选择已分组的行,即使它们不在该另一个表中

时间:2012-08-29 14:44:14

标签: mysql sql join

标题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小提琴中,我想要Zack Jones的另一行,显示他在组0中,或者是NULL或者其他东西!)

6 个答案:

答案 0 :(得分:4)

您应该在桌面上使用LEFT JOIN,而您不确定匹配是否可用。在你的情况下,你应该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

答案 1 :(得分: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

一般使用explicit JOINs, not implied-WHERE JOINS。在这种情况下,请使用LEFT OUTER JOIN

此外,不要依赖MySQL GROUP BY扩展:they don't always work as expected

答案 2 :(得分: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_membersusers

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

答案 3 :(得分: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

答案 4 :(得分:1)

在这些情况下,外部联接非常有用。我已经交换了用户和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

答案 5 :(得分: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

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