我被要求解决这个问题:

问题描述 投票:0回答:1
city

(state_name,no_big_city,big_city_population)
订购,列出了(a)至少五个大城市或(b)至少一百万居住在大城市的州。该列是该州的大城市的数量,是该州的大城市的数量,是居住在该州大城市的人数。

,据我所知,以下查询返回正确的结果:
state_name
冗长的聚合函数表达式出现两次。
在保留功能时,有任何方法可以避免代码重复吗?

我已经尝试使用别名,但是我只是得到“列不存在”错误。
    
	
手册澄清:


  
AN输出列的名称可用于参考该列的值
state_name

name
子句,但不在

state

no_big_city


子句中; 您必须改为写出表达式。 bold重点是我的 您可以避免使用子查询或CTE反复键入长表达式:

big_city_population

sql postgresql case aggregate-functions having
1个回答
8
投票

我如何简化此游戏统计信息查询?

,但是,我建议以下更简单,更快的查询:

SELECT state.name AS state_name
     , COUNT(CASE WHEN place.type = 'city' AND place.population >= 100000 THEN 1 ELSE NULL END) AS no_big_city
     , SUM  (CASE WHEN place.type = 'city' AND place.population >= 100000 THEN place.population ELSE NULL END) AS big_city_population
FROM state
JOIN place ON state.code = place.state_code
GROUP BY state_name
HAVING COUNT(CASE WHEN place.type = 'city' AND place.population >= 100000 THEN 1 ELSE NULL END) >= 5
    OR SUM  (CASE WHEN place.type = 'city' AND place.population >= 100000 THEN place.population ELSE NULL END) >= 1000000
ORDER BY state_name;
我正在演示另一种选择在
ORDER BY
GROUP BY
中引用表达式的选项。仅在不损害可读性和可维护性的情况下使用它。
确保这是评论还是答案,因为它比技术相反,但我无论如何都会发布它

当我需要参考计算的列(通常同时大量)时,我通常会做什么是将计算出的列放入派生的表中,然后使用其在派生表之外使用其别名来引用计算的列。该语法应该是正确的,但我不熟悉Postgres WHERE

关于这种方法的好处是,尽管您正在通过子查询/派生表添加并发症,但该公式仍将其保存在一个地方,因此任何更改都必须发生一次。我不知道这比简单地重复小组中的计算能力更糟糕,但是我无法想象会更糟。

选择子句是您要从Where子句表(s)中选择的。 组为一个条件,如何将过滤记录分组到选择中的聚合功能中。因此,别名不能在那里。 但是您可以包装过过滤的记录并从中选择。这样的东西:
HAVING

也是移动条件

SELECT state_name, no_big_city, big_city_population FROM ( SELECT s.name AS state_name , COUNT(*) FILTER (WHERE p.type = 'city' AND p.population >= 100000) AS no_big_city , SUM(population) FILTER (WHERE p.type = 'city' AND p.population >= 100000) AS big_city_population FROM state s JOIN place p ON s.code = p.state_code GROUP BY s.name -- can be input column name as well, best schema-qualified to avoid ambiguity ) sub WHERE no_big_city >= 5 OR big_city_population >= 1000000 ORDER BY state_name;
    case of case会表现更好。不会处理“没有城市”或“小城市记录”。特别是如果索引有索引。
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.