PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Come riutilizzare il risultato per le clausole SELECT, WHERE e ORDER BY?

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.