problema alias colonna postgres
-
22-07-2019 - |
Domanda
Come principiante di Postgresql (mi sto spostando perché sto trasferendo il mio sito su heroku che lo supporta solo, devo refactificare alcune delle mie query e del mio codice. Ecco un problema che non riesco proprio capire il problema con:
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 ...
^
... La ricerca:
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
clausola " l.user_id come l_user_id, l.geopoint_id come l_geopoint_id " è stato aggiunto perché apparentemente a Postgres non piacciono le clausole d'ordine con campi non selezionati. Ma l'errore che ricevo ora fa sembrare che anche io non stia ottenendo aliasing. Qualcuno con esperienza postgres vede il problema?
Probabilmente avrò un sacco di questi problemi - le query hanno funzionato bene in mySql ...
Soluzione
In PostgreSQL non puoi usare expression con un alias in ordine di. Solo i semplici alias funzionano lì. La tua query dovrebbe apparire così:
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;
Suppongo che intendi che l2.user_id = l.user_id
dovrebbe essere il primo.
Questo è un messaggio rilevante sulla mailing list di PostgreSQL-general . Quanto segue è nella di ORDER BY
clausola :
Ogni espressione può essere il nome o numero ordinale di un output colonna (SELEZIONA elemento dell'elenco) oppure può essere una espressione arbitraria formata da valori della colonna di input .
Quindi nessun alias quando si usa l'espressione.
Altri suggerimenti
Hai:
order by l2.geopoint_id, l_user_id = l2.user_id desc
nella tua query. Questa è sintassi illegale. Rimuovi la parte = l2.user_id
(spostala su dove
se questa è una delle condizioni di join) e dovrebbe funzionare.
Aggiorna In basso selezionare (con = l2.user_id
rimosso) dovrebbe funzionare bene. L'ho provato (con nomi di tabella / colonna diversi, ovviamente) su 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
Ho riscontrato questo stesso problema usando le funzioni di fuzzystrmatch, in particolare la funzione levenshtein. Avevo bisogno sia di ordinare in base alla distanza della stringa, sia di filtrare i risultati in base alla distanza della stringa. Inizialmente stavo provando:
SELECT thing.*,
levenshtein(thing.name, '%s') AS dist
FROM thing
WHERE dist < character_length(thing.name)/2
ORDER BY dist
Ma, naturalmente, ho ricevuto l'errore "colonna" dist ". non esiste " dalla clausola WHERE. Ho provato questo e ha funzionato:
SELECT thing.*,
(levenshtein(thing.name, '%s')) AS dist
FROM thing
ORDER BY dist
Ma avevo bisogno di avere quella qualifica nella clausola WHERE. Qualcun altro in questa domanda ha affermato che la clausola WHERE viene valutata prima di ORDER BY, quindi la colonna era inesistente quando ha valutato la clausola WHERE. Seguendo quel consiglio, ho capito che un'istruzione SELECT nidificata fa il trucco:
SELECT * FROM
(SELECT thing.*,
(levenshtein(thing.name, '%s')) AS dist
FROM thing
ORDER BY dist
) items
WHERE dist < (character_length(items.name)/2)
Tieni presente che gli articoli " " l'alias della tabella è richiesto e l'alias della colonna dist è accessibile nel SELECT esterno perché è univoco nell'istruzione. È un po 'funky e sono sorpreso che debba essere così in PG - ma non sembra subire un successo prestazionale, quindi sono soddisfatto.
" è stato aggiunto perché apparentemente a Postgres non piacciono le clausole d'ordine con campi non selezionati "
" Per quanto riguarda l'ordine, sì, PostgresQL (e molti altri database) non consente l'ordinamento per colonne che non sono elencate nella clausola select. "
Semplicemente falso.
= > SELEZIONA ID DA t1 ORDINA PER LIMITE proprietario 5;
id
30 10 20 50 40 (5 righe)