显示组中的用户数,甚至是空组

时间:2012-01-03 18:36:05

标签: mysql group-by

我正在尝试提取有关每个用户组的信息,同时计算每个用户组中的用户数。 计数有效,但是如果一个组不包含任何用户,则它不会检索信息 - 它只会被忽略。

这是我的疑问:

 SELECT
       g.*,
       count(u.username) as total,
       u.usergroup
  FROM
      usergroups as g,
      users as u
  WHERE
      u.usergroup = g.g_id
  GROUP BY
      g.group_name

这是我的“用户”和“用户组”表格的一部分:

 Sample usergroups table structure
  +--------------------------+---------------+
  | Field                    | Type          |
  +--------------------------+---------------+
  | g_id                     | int(10)       |<- the user group's ID.
  | group_name               | varchar(255)  |<- the name of the user group
  +--------------------------+---------------+

  Sample users table structure
  +--------------------------+---------------+
  | Field                    | Type          |
  +--------------------------+---------------+
  | id                       | int(10)       |<- the user ID
  | username                 | varchar(255)  |<- the username
  | usergroup                | int(10)       |<- ID of the user group the user is in
  +--------------------------+---------------+

我不知道我错过了什么 - 但话说回来,我对更复杂的查询非常陌生(如果你可以称之为)。

非常感谢任何帮助!

2 个答案:

答案 0 :(得分:8)

你想要一个left join,而你正在做inner join

 SELECT
       g.*,
       count(u.username) as total,
       u.usergroup
  FROM
      usergroups as g
      left join users as u on
           g.u_id = u.usergroup
  GROUP BY
      g.u_id,
      g.group_name

现在我引起了你的注意,我想花点时间讨论一下加入条件是什么。看,当你第一次学习MySQL时,他们会教你使用的语法。对于某些问题,嘿,它的效果很好。不幸的是,它会让你将“连接条件”等同于“where predicate”,这是一个问题。

在这种情况下,我们说,“嘿,MySQL,抓住usergroups表中的所有内容,并尝试找到users表中u_id表的匹配项来自usergroups的1}}列等于来自usergroup的{​​{1}}列。如果您找不到任何内容,那就可以了,无论如何都要退回users,然后将其归零usergroup带来的列。“

以前,你说,“嘿,MySQL,从usersusergroups表中抓取所有内容,但仅限usersu_id }}匹配usergroups中的usergroup列。“

如果您使用users语法完成此操作,请执行以下操作:

inner join

你会说,“嘿,MySQL,从 SELECT g.*, count(u.username) as total, u.usergroup FROM usergroups as g inner join users as u on g.u_id = u.usergroup GROUP BY g.u_id, g.group_name 表中抓取我的所有内容,然后在usergroups表中查找users等于{{1}的所有内容如果找不到匹配项,我不希望看到该用户组显示在结果中。

因此,要清楚,where谓词过滤结果集,而连接条件一个表映射到另一个表。

答案 1 :(得分:3)

你需要在这里使用LEFT JOIN而不是隐含的INNER JOIN:

SELECT
       g.*,
       count(u.username) as total,
       u.usergroup
  FROM
      usergroups as g
  LEFT JOIN users as u ON g.g_id = u.usergroup
  GROUP BY
      g.group_name