problème d'alias de colonne postgres
-
22-07-2019 - |
Question
En tant que débutant chez Postgresql (je déménage parce que je déplace mon site vers heroku, qui ne le supporte que, je dois reformuler certaines de mes requêtes et mon code. Voici un problème que je ne parviens pas à comprendre. comprendre le problème avec:
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 ...
^
... requête:
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
clause "quot.user_id comme id_utilisateur, l.geopoint_id comme l_geopoint_id" a été ajouté car apparemment postgres n'aime pas les clauses d'ordre avec les champs non sélectionnés. Mais l'erreur que j'ai maintenant donne à penser que je ne reçois pas d'alias. Quelqu'un avec une expérience postgres voit le problème?
Je risque fort de rencontrer plusieurs de ces problèmes - les requêtes ont bien fonctionné dans mySql ...
La solution
Dans PostgreSQL, vous ne pouvez pas utiliser d’expression avec un alias dans l’ordre. Seuls les pseudonymes simples y travaillent. Votre requête devrait ressembler à ceci:
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;
Je suppose que vous voulez dire que l2.user_id = l.user_id
doit commencer en premier.
Ce message est pertinent sur la liste de diffusion de PostgreSQL - general . Les informations suivantes figurent dans la documentation sur ORDER BY
clause :
Chaque expression peut être le nom ou nombre ordinal d'une sortie colonne (élément de liste SELECT) ou peut être une expression arbitraire formée à partir des colonnes d'entrée , valeurs .
Donc, pas d'alias lorsque l'expression est utilisée.
Autres conseils
Vous avez:
order by l2.geopoint_id, l_user_id = l2.user_id desc
dans votre requête. C'est une syntaxe illégale. Supprimez la partie = l2.user_id
(déplacez-la vers où
s'il s'agit de l'une des conditions de jointure) et cela devrait fonctionner.
Mettre à jour la sélection ci-dessous (avec = l2.user_id
supprimé) devrait fonctionner correctement. Je l'ai testé (avec différents noms de table / colonne, évidemment) sur 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
J'ai rencontré le même problème avec les fonctions de fuzzystrmatch, en particulier la fonction levenshtein. J'avais besoin de trier par la distance de chaîne et de filtrer les résultats par la distance de chaîne. J'essayais à l'origine:
SELECT thing.*,
levenshtein(thing.name, '%s') AS dist
FROM thing
WHERE dist < character_length(thing.name)/2
ORDER BY dist
Mais, bien sûr, l'erreur "colonne" a été générée. n'existe pas " de la clause WHERE. J'ai essayé cela et cela a fonctionné:
SELECT thing.*,
(levenshtein(thing.name, '%s')) AS dist
FROM thing
ORDER BY dist
Mais je devais avoir cette qualification dans la clause WHERE. Quelqu'un d'autre dans cette question a déclaré que la clause WHERE était évaluée avant ORDER BY. La colonne était donc inexistante lorsqu'elle évaluait la clause WHERE. En me basant sur ce conseil, j'ai compris qu'une instruction SELECT imbriquée faisait l'affaire:
SELECT * FROM
(SELECT thing.*,
(levenshtein(thing.name, '%s')) AS dist
FROM thing
ORDER BY dist
) items
WHERE dist < (character_length(items.name)/2)
Notez que les " éléments " Un alias de table est requis et l'alias de colonne dist est accessible dans le SELECT externe, car il est unique dans l'instruction. C'est un peu génial et je suis surpris que cela soit le cas chez PG - mais cela ne semble pas prendre un coup dur pour la performance, donc je suis satisfait.
"a été ajouté car apparemment postgres n'aime pas les clauses d'ordre avec des champs non sélectionnés"
"Pour ce qui est du classement par ordre, oui, PostgresQL (et de nombreuses autres bases de données) n'autorise pas le classement par colonnes non répertoriées dans la clause select."
Tout simplement faux.
= > SELECT ID FROM t1 ORDER BY owner LIMIT 5;
id
30 dix 20 50 40 (5 lignes)