Im Feld GROUP BY
und ORDER BY
-Klausel können Sie sich auf Spaltenaliase (Ausgabespalten) oder sogar Ordnungszahlen von SELECT
beziehen Artikel auflisten. Ich zitiere das Handbuch auf ORDER BY
:
Jeder Ausdruck kann der Name oder die Ordnungszahl einer Ausgabespalte (Element der SELECT-Liste) sein , oder es kann ein beliebiger Ausdruck sein, der aus Eingabespaltenwerten gebildet wird.
Fettdruck von mir.
Aber im WHERE
und HAVING
Klauseln können Sie nur auf Spalten aus den Basistabellen (Eingabespalten) verweisen, also müssen Sie Ihren Funktionsaufruf buchstabieren.
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;
Wenn Sie wissen möchten, ob es schneller ist, die Berechnung in einen CTE oder eine Unterabfrage zu packen, testen Sie es einfach mit EXPLAIN ANALYZE
. (Ich bezweifle es.)
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;
Wie @Mike kommentierte, indem eine Funktion STABLE
deklariert wurde (oder IMMUTABLE
) teilen Sie dem Abfrageplaner mit, dass Ergebnisse eines Funktionsaufrufs mehrfach für identische Aufrufe innerhalb einer einzigen Anweisung wiederverwendet werden können. Ich zitiere das Handbuch hier:
Eine STABLE-Funktion kann die Datenbank nicht ändern und gibt garantiert dieselben Ergebnisse zurück, wenn dieselben Argumente für alle Zeilen innerhalb einer einzigen Anweisung gegeben werden. Diese Kategorie ermöglicht es dem Optimierer, mehrere Aufrufe der Funktion zu einem einzigen Aufruf zu optimieren .
Fettdruck von mir.