从具有group by的联接中的ID获取列

时间:2016-01-14 20:13:57

标签: sql postgresql

我有两张桌子: 地点和用户。用户有一个location_id集,这是与locations表的一对多关系。

我正在尝试计算有多少用户属于某个位置。

到目前为止,我有一个问题:

SELECT users.location_id, locations.name FROM users 
LEFT JOIN locations on locations.id = users.location_id

但这并没有归还计数。我尝试使用Group By,但我不熟悉它是如何工作的。

3 个答案:

答案 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  

第二种和第三种解决方案的性能相同。