PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Comment réutiliser le résultat pour les clauses SELECT, WHERE et ORDER BY ?

Dans le GROUP BY et ORDER BY clause, vous pouvez faire référence à des alias de colonne (colonnes de sortie) ou même à des nombres ordinaux de SELECT éléments de la liste. Je cite le manuel sur ORDER BY :

Chaque expression peut être le nom ou le nombre ordinal d'une colonne de sortie (élément de liste SELECT) , ou il peut s'agir d'une expression arbitraire formée à partir de valeurs de colonne d'entrée.

J'insiste sur moi.

Mais dans le WHERE et HAVING clauses, vous ne pouvez faire référence qu'aux colonnes des tables de base (colonnes d'entrée), vous devez donc épeler votre appel de fonction.

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;

Si vous voulez savoir s'il est plus rapide de regrouper le calcul dans un CTE ou une sous-requête, testez-le simplement avec EXPLAIN ANALYZE . (J'en doute.)

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;

Comme @Mike l'a commenté, en déclarant une fonction STABLE (ou IMMUTABLE ) vous informez le planificateur de requêtes que les résultats d'un appel de fonction peuvent être réutilisés plusieurs fois pour des appels identiques au sein d'une même instruction. Je cite le manuel ici :

Une fonction STABLE ne peut pas modifier la base de données et est garantie de renvoyer les mêmes résultats avec les mêmes arguments pour toutes les lignes d'une seule instruction. Cette catégorie permet à l'optimiseur d'optimiser plusieurs appels de la fonction en un seul appel .

J'insiste sur moi.