在 GROUP BY 和 COUNT 之后加入另一个表

Cra*_*g S 8 sql group-by count aggregate-functions left-join

我试图了解使用JOINCOUNT(*)GROUP BY进行非常简单的查询的正确方法。我实际上已经让它工作了(见下文),但从我读到的内容来看,我使用了GROUP BY不应该使用的额外内容。

(注意:下面的问题不是我的实际问题(它处理更复杂的表),但我试图提出一个类似的问题)

我有两张桌子:

Table: Person
-------------
key  name     cityKey
1    Alice    1
2    Bob      2
3    Charles  2
4    David    1

Table: City
-------------
key  name
1    Albany
2    Berkeley
3    Chico
Run Code Online (Sandbox Code Playgroud)

我想对WHERE返回的 People (带有一些子句)进行查询

  • 每个城市的匹配人数
  • 城市的钥匙
  • 城市的名称。

如果我做

SELECT COUNT(Person.key) AS count, City.key AS cityKey, City.name AS cityName
FROM Person 
LEFT JOIN City ON Person.cityKey = City.key 
GROUP BY Person.cityKey, City.name
Run Code Online (Sandbox Code Playgroud)

我得到了我想要的结果

count   cityKey   cityName
2       1         Albany
2       2         Berkeley
Run Code Online (Sandbox Code Playgroud)

然而,我读到,仅仅为了使其工作 而添加子句的最后一部分GROUP BY( ) 是错误的。City.name

那么这样做的正确方法是什么?我一直在尝试用谷歌搜索答案,但我觉得有一些基本的东西我没有得到。

Poi*_*nty 5

我不认为在这种情况下这是“错误的”,因为城市名称和城市密钥之间存在一对一的关系。您可以重写它,以便加入子选择以按键获取城市的人数,然后再次获取城市表的名称,但这是有争议的,这是否会更好。我想这是风格和观点的问题。

select PC.ct, City.key, City.name
  from City
  join (select count(Person.key) ct, cityKey key from Person group by cityKey) PC
    on City.key = PC.key
Run Code Online (Sandbox Code Playgroud)

如果我的 SQL 不是太生疏的话:-)


And*_*mar 1

您的查询只能在 MySQL 上运行,因为您对Person.cityKey但选择了分组city.key。所有其他数据库都需要您使用类似 , 的聚合min(city.key),或者添加City.keygroup by子句中。

由于城市名称和城市键的组合是唯一的,因此以下内容是等效的:

select    count(person.key), min(city.key), min(city.name)
...
group by  person.citykey
Run Code Online (Sandbox Code Playgroud)

或者:

select    count(person.key), city.key, city.name
...
group by  person.citykey, city.key, city.name
Run Code Online (Sandbox Code Playgroud)

或者:

select    count(person.key), city.key, max(city.name)
...
group by  city.key
Run Code Online (Sandbox Code Playgroud)

组中的所有行都将具有相同的城市名称和键,因此使用maxmin聚合并不重要。

PS 如果您只想计算不同的人,即使他们有多行,请尝试:

count(DISTINCT person.key)
Run Code Online (Sandbox Code Playgroud)

代替

count(person.key)
Run Code Online (Sandbox Code Playgroud)