排除重复连接记录的列的总和

问题描述 投票:0回答:2

假设我有一个包含城市及其人口的表和一个包含不同类型建筑物的表。我想知道居住在有学校的城市的人口百分比。

城市:

名字 流行
A 10
B 100
C 1000

建筑物:

是_学校 城市
A
真实 B
真实 B
真实 C

如果我做这样的事情:

SELECT
  SUM(CASE WHEN building.is_school = true THEN city.pop ELSE 0 END) school,
  SUM(city.pop) total
FROM city
LEFT JOIN building ON building.city = city.name;

我将 B 城市人口加起来两次。 我想要:

学校 总计
1100 1110

但我得到:

学校 总计
1200 1210

小提琴

我可以做一个子查询:

SELECT
  SUM(CASE WHEN city.name in (
    SELECT city.name
    FROM city
    LEFT JOIN building ON building.city = city.name
    WHERE building.is_school = true
  ) THEN city.pop ELSE 0 END),
  SUM(city.pop)
FROM city;

但考虑到我想要实现的目标,感觉没有必要复杂,真的没有其他方法吗?

sql postgresql join duplicates sum
2个回答
0
投票

你可以这样做:

SELECT
  1.0 * sum(case when exists (
  select 1 from building b where b.city = c.name and is_school) then 1 else 0 end)
  / count(*)
FROM city c;

结果:

?column?
--------
0.66666666666666666667

请参阅 db<>fiddle 处的运行示例。


0
投票

您可以使用的另一种方法是加入建筑物的过滤版本而不是建筑物本身

SELECT
  SUM(CASE WHEN building.is_school = true THEN city.pop ELSE 0 END) school, SUM(city.pop) total
FROM city
LEFT JOIN (SELECT DISTINCT city, is_school FROM building) building ON building.city = city.name;

对于庞大的数据库,不建议使用DISTINCT,因为确定不同记录的过程非常慢,但至少查询是苗条可爱的

© www.soinside.com 2019 - 2024. All rights reserved.