我正在尝试提取有关每个用户组的信息,同时计算每个用户组中的用户数。 计数有效,但是如果一个组不包含任何用户,则它不会检索信息 - 它只会被忽略。
这是我的疑问:
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
+--------------------------+---------------+
我不知道我错过了什么 - 但话说回来,我对更复杂的查询非常陌生(如果你可以称之为)。
非常感谢任何帮助!
答案 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,从users
和usergroups
表中抓取所有内容,但仅限users
列u_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