PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Como reutilizar o resultado para as cláusulas SELECT, WHERE e ORDER BY?


No GROUP BY e ORDER BY cláusula você pode fazer referência a aliases de coluna (colunas de saída) ou até mesmo números ordinais de SELECT lista de itens. Cito o manual em ORDER BY :

Cada expressão pode ser o nome ou número ordinal de uma coluna de saída (SELECT item de lista) , ou pode ser uma expressão arbitrária formada a partir de valores da coluna de entrada.

Minha ênfase em negrito.

Mas no WHERE e HAVING cláusulas, você só pode se referir a colunas das tabelas base (colunas de entrada), então você tem que soletrar sua chamada de função.
SELECT *, earth_distance(ll_to_earth(62.0, 25.0), ll_to_earth(lat, lon)) AS dist
FROM   venues 
WHERE  earth_distance(ll_to_earth(62.0, 25.0), ll_to_earth(lat, lon)) <= radius 
ORDER  BY distance;

Se você quiser saber se é mais rápido empacotar o cálculo em um CTE ou subconsulta, basta testá-lo com EXPLAIN ANALYZE . (Eu duvido.)
SELECT *
FROM  (
   SELECT *
         ,earth_distance(ll_to_earth(62.0, 25.0), ll_to_earth(lat, lon)) AS dist
   FROM   venues
   ) x
WHERE  distance <= radius 
ORDER  BY distance;

Como @Mike comentou, declarando uma função STABLE (ou IMMUTABLE ), você informa ao planejador de consultas que os resultados de uma chamada de função podem ser reutilizados várias vezes para chamadas idênticas em uma única instrução. Cito o manual aqui:

Uma função STABLE não pode modificar o banco de dados e tem a garantia de retornar os mesmos resultados com os mesmos argumentos para todas as linhas em uma única instrução. Esta categoria permite que o otimizador otimize várias chamadas da função para uma única chamada .

Minha ênfase em negrito.