In de GROUP BY
en ORDER BY
clausule kunt u verwijzen naar kolomaliassen (uitvoerkolommen) of zelfs rangtelwoorden van SELECT
lijst items. Ik citeer de handleiding op ORDER BY
:
Elke uitdrukking kan de naam of het rangtelwoord van een uitvoerkolom zijn (SELECT lijstitem) , of het kan een willekeurige uitdrukking zijn die wordt gevormd uit invoerkolomwaarden.
Vetgedrukte nadruk van mij.
Maar in de WHERE
en HAVING
clausules, kunt u alleen verwijzen naar kolommen uit de basistabellen (invoerkolommen), dus u moet uw functieaanroep spellen.
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;
Als je wilt weten of het sneller is om de berekening in een CTE of subquery in te pakken, test het dan gewoon met EXPLAIN ANALYZE
. (Ik betwijfel het.)
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;
Zoals @Mike commentaar gaf, door een functie STABLE
te declareren (of IMMUTABLE
) informeer je de queryplanner dat resultaten van een functieaanroep meerdere keren kunnen worden hergebruikt voor identieke aanroepen binnen een enkele instructie. Ik citeer hier de handleiding:
Een STABLE-functie kan de database niet wijzigen en levert gegarandeerd dezelfde resultaten op met dezelfde argumenten voor alle rijen binnen een enkele instructie. Met deze categorie kan de optimizer meerdere aanroepen van de functie tot één aanroep optimaliseren .
Vetgedrukte nadruk van mij.