手册明确: https://www.postgresql.org/docs/current/static/sql-select.html#SQL-SELECT-LIST
输出列的名称可用于引用该列的值ORDER BY
and GROUP BY
条款,但不在WHERE
or HAVING
条款;在那里你必须写出表达式。
大胆强调我的。
您可以避免使用子查询或 CTE 重复输入长表达式:
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;
在做这件事时,我简化了总体FILTER
子句(Postgres 9.4+):
- 如何简化这个游戏统计查询? https://stackoverflow.com/questions/27136251/how-can-i-simplify-this-game-statistics-query/27141193#27141193
不过,我建议从这个更简单、更快的查询开始:
SELECT s.state_name, p.no_big_city, p.big_city_population
FROM state s
JOIN (
SELECT state_code AS code -- alias just to simplify join
, count(*) AS no_big_city
, sum(population) AS big_city_population
FROM place
WHERE type = 'city'
AND population >= 100000
GROUP BY 1 -- can be ordinal number referencing position in SELECT list
HAVING count(*) >= 5 OR sum(population) >= 1000000 -- simple expressions now
) p USING (code)
ORDER BY 1; -- can also be ordinal number
我正在演示另一个引用表达式的选项GROUP BY
and ORDER BY
。仅在不损害可读性和可维护性的情况下才使用它。