Nel GROUP BY
e ORDER BY
clausola puoi fare riferimento ad alias di colonna (colonne di output) o anche numeri ordinali di SELECT
Elementi della lista. Cito il manuale su ORDER BY
:
Ciascuna espressione può essere il nome o il numero ordinale di una colonna di output (SELECT elemento dell'elenco) oppure può essere un'espressione arbitraria formata da valori della colonna di input.
Enfasi in grassetto la mia.
Ma nel WHERE
e HAVING
clausole, puoi fare riferimento solo alle colonne delle tabelle di base (colonne di input), quindi devi scrivere la tua chiamata di funzione.
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 vuoi sapere se è più veloce comprimere il calcolo in una CTE o sottoquery, provalo con EXPLAIN ANALYZE
. (Ne dubito.)
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;
Come ha commentato @Mike, dichiarando una funzione STABLE
(o IMMUTABLE
) informi il pianificatore di query che i risultati di una chiamata di funzione possono essere riutilizzati più volte per chiamate identiche all'interno di una singola istruzione. Cito il manuale qui:
Una funzione STABLE non può modificare il database ed è garantito che restituisca gli stessi risultati dati gli stessi argomenti per tutte le righe all'interno di una singola istruzione. Questa categoria consente all'ottimizzatore di ottimizzare più chiamate della funzione in una singola chiamata .
Enfasi in grassetto la mia.