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.