我有两张桌子: 地点和用户。用户有一个location_id集,这是与locations表的一对多关系。
我正在尝试计算有多少用户属于某个位置。
到目前为止,我有一个问题:
SELECT users.location_id, locations.name FROM users
LEFT JOIN locations on locations.id = users.location_id
但这并没有归还计数。我尝试使用Group By,但我不熟悉它是如何工作的。
答案 0 :(得分:2)
您可以将聚合count()函数与GROUP BY:
一起使用SELECT l.id, l.name, count(u.id)
FROM locations l
LEFT JOIN users u
ON l.id = u.location_id
GROUP BY l.id, l.name
答案 1 :(得分:1)
使用“计数”功能。如果没有GROUP BY子句,count将返回查询返回的行数。使用GROUP BY子句,count返回为每个组返回的行数。查询的SELECT部分中的项目只能包含GROUP BY子句中的列和/或聚合函数(如“count”)。
SELECT count(*), users.location_id, locations.name FROM users
LEFT JOIN locations on locations.id = users.location_id
GROUP BY users.location_id, locations.name
看来很明显,locations.id是您情况下的唯一键。如果不是,那么您将为locations.id和locations.name的每个唯一组合获得另一个“组”,以及该组的计数。
答案 2 :(得分:1)
您想要所有位置,因此查询必须采用以下形式:位置LEFT JOIN用户。
SELECT locations.id, locations.name, count(*) as usersCount
FROM locations
LEFT JOIN users on locations.id = users.location_id
GROUP BY locations.id, locations.name
这是正确的,但想象一下,位置有十列,你想要它们全部。你会按十列分组吗?你必须这样做,但效率很低。您希望在可能的最低级别进行分组
SELECT locations.id, locations.name, usersCount
FROM locations
LEFT JOIN (SELECT users.location_id, count(*) AS usersCount
FROM users GROUP BY users.location_id) AS usersTable
ON locations.id = usersTable.location_id
或者只使用相关子查询(我最喜欢的选择)
SELECT locations.id, locations.name,
(SELECT count(*) FROM users
WHERE users.location_id = locations.id) AS usersCount
FROM locations
第二种和第三种解决方案的性能相同。