Problem mit dem Postgres-Spaltenalias
-
22-07-2019 - |
Frage
Als Neuling bei Postgresql (ich wechsle um, weil ich meine Website zu Heroku verschiebe, die es nur unterstützen), muss ich einige meiner Abfragen und meinen Code umgestalten.Hier ist ein Problem, dessen Problem ich nicht ganz verstehen kann:
PGError: ERROR: column "l_user_id" does not exist
LINE 1: ...t_id where l.user_id = 8 order by l2.geopoint_id, l_user_id ...
^
...Abfrage:
select distinct
l2.*,
l.user_id as l_user_id,
l.geopoint_id as l_geopoint_id
from locations l
left join locations l2 on l.geopoint_id = l2.geopoint_id
where l.user_id = 8
order by l2.geopoint_id, l_user_id = l2.user_id desc
Die Klausel „l.user_id as l_user_id, l.geopoint_id as l_geopoint_id“ wurde hinzugefügt, da Postgres offenbar keine Bestellklauseln mit nicht ausgewählten Feldern mag.Aber der Fehler, den ich jetzt erhalte, lässt es so aussehen, als würde ich auch kein Aliasing erhalten.Erkennt jemand mit Postgres-Erfahrung das Problem?
Ich habe wahrscheinlich eine Reihe dieser Probleme – die Abfragen haben in MySQL einwandfrei funktioniert ...
Lösung
In PostgreSQL kann man nicht mit einem Aliasnamen verwenden, um die Expression durch. Nur dort arbeiten Ebene Aliase. Ihre Abfrage sollte wie folgt aussehen:
select distinct
l2.*,
l.user_id as l_user_id,
l.geopoint_id as l_geopoint_id
from locations l
left join locations l2 on l.geopoint_id = l2.geopoint_id
where l.user_id = 8
order by l2.geopoint_id, l.user_id = l2.user_id desc;
Ich nehme an, Sie bedeuten, dass l2.user_id=l.user_id
sollte zuerst gehen.
Dies ist relevant Nachricht auf PostgreSQL-allgemeine Mailingliste . Hier finden Sie in der Dokumentation von ORDER BY
Klausel :
Jeder Ausdruck kann der Name oder Ordnungszahl eines Ausgang Spalte (SELECT Artikelliste), oder sein ein kann beliebiger Ausdruck gebildet Eingabe-Spalte Werte .
Also keine Aliase, wenn die Expression verwendet wird.
Andere Tipps
Sie haben:
order by l2.geopoint_id, l_user_id = l2.user_id desc
in der Abfrage. Das ist illegal Syntax. Entfernen Sie den = l2.user_id
Teil (verschieben Sie es in where
wenn das eine der Join-Bedingungen) und es sollte funktionieren.
Aktualisieren Im Folgenden wählen Sie (mit = l2.user_id
entfernt) sollte gut funktionieren. Ich habe es getestet (mit unterschiedlichen Tabelle / Spaltennamen, natürlich) auf Postgres 8.3
select distinct
l2.*,
l.user_id as l_user_id,
l.geopoint_id as l_geopoint_id
from locations l
left join locations l2 on l.geopoint_id = l2.geopoint_id
where l.user_id = 8
order by l2.geopoint_id, l_user_id desc
Ich bin auf dasselbe Problem gestoßen, als ich Funktionen von fuzzystrmatch verwendet habe – insbesondere die Levenshtein-Funktion.Ich musste sowohl nach dem String-Abstand sortieren als auch die Ergebnisse nach dem String-Abstand filtern.Ich habe ursprünglich versucht:
SELECT thing.*,
levenshtein(thing.name, '%s') AS dist
FROM thing
WHERE dist < character_length(thing.name)/2
ORDER BY dist
Aber natürlich habe ich aufgrund der WHERE-Klausel die Fehlermeldung „Spalte „dist“ existiert nicht“ erhalten.Ich habe es versucht und es hat funktioniert:
SELECT thing.*,
(levenshtein(thing.name, '%s')) AS dist
FROM thing
ORDER BY dist
Aber ich brauchte diese Qualifikation in der WHERE-Klausel.Jemand anderes in dieser Frage sagte, dass die WHERE-Klausel vor ORDER BY ausgewertet wird und die Spalte daher nicht vorhanden war, als die WHERE-Klausel ausgewertet wurde.Anhand dieses Ratschlags habe ich herausgefunden, dass eine verschachtelte SELECT-Anweisung den Zweck erfüllt:
SELECT * FROM
(SELECT thing.*,
(levenshtein(thing.name, '%s')) AS dist
FROM thing
ORDER BY dist
) items
WHERE dist < (character_length(items.name)/2)
Beachten Sie, dass der Tabellenalias „items“ erforderlich ist und der Spaltenalias „dist“ in der äußeren SELECT-Anweisung zugänglich ist, da er in der Anweisung eindeutig ist.Es ist ein bisschen unkonventionell und ich bin überrascht, dass es in PG so sein muss – aber es scheint keinen Leistungseinbruch zu erleiden, also bin ich zufrieden.
„wurde hinzugefügt, weil offenbar postgres nicht um Klauseln mit Feldern wie nicht ausgewählt“
„Soweit Ordnung vergeht -. Ja, PostgresQL (und viele andere Datenbanken) erlauben keine Bestellung von Spalten, die nicht in select-Klausel aufgeführt sind“
Einfach nur falsch.
=> SELECT id FROM t1 ORDER BY Inhaber LIMIT 5;
id
30 10 20 50 40 (5 Zeilen)