problema postgres coluna de alias
-
22-07-2019 - |
Pergunta
Como um novato ao PostgreSQL (estou movendo-se sobre porque eu estou mudando meu site para heroku que só apoiá-lo, eu estou tendo que refazer algumas das minhas consultas e código. Aqui é um problema que eu não consigo entender o problema com:
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 ...
^
... consulta:
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
cláusula "l.user_id como l_user_id, l.geopoint_id como l_geopoint_id" foi adicionado porque aparentemente postgres não gosta cláusulas de ordem com campos não selecionado. Mas o erro agora recebo faz com que pareça como se eu também não estou recebendo aliasing. Qualquer pessoa com experiência postgres ver o problema?
Eu sou propensos a ter um monte desses problemas - as consultas funcionou bem no MySQL ...
Solução
Em PostgreSQL você não pode usar a expressão com um alias, a fim de. Somente aliases simples trabalhar lá. Sua consulta deve ser semelhante a este:
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;
Eu suponho que você quer dizer que l2.user_id=l.user_id
deve ir primeiro.
Este é mensagem relevante na lista de discussão do PostgreSQL-geral . O seguinte é na documentação da cláusula ORDER BY
:
Cada expressão pode ser o nome ou número ordinal de uma saída coluna (item de lista SELECT), ou pode ser um expressão arbitrária formada de das colunas da entrada valores .
Assim, há aliases quando a expressão utilizada.
Outras dicas
Você tem:
order by l2.geopoint_id, l_user_id = l2.user_id desc
em sua consulta. Essa é a sintaxe ilegal. Remova a parte = l2.user_id
(movê-lo para where
se isso é uma das condições de junção) e ele deve funcionar.
Atualizar A seguir, selecione (com = l2.user_id
removido) deve funcionar muito bem. Eu testei-o (com diferentes nomes de tabela / coluna, obviamente) em 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
Corri para este mesmo problema usando as funções de fuzzystrmatch - particularmente a função levenshtein. Eu precisava tanto espécie pela distância corda, e resultados do filtro pela distância string. Eu estava originalmente tentando:
SELECT thing.*,
levenshtein(thing.name, '%s') AS dist
FROM thing
WHERE dist < character_length(thing.name)/2
ORDER BY dist
Mas, é claro, eu tenho o erro dist "coluna" "não existe" da cláusula WHERE. Eu tentei isso e deu certo:
SELECT thing.*,
(levenshtein(thing.name, '%s')) AS dist
FROM thing
ORDER BY dist
Mas eu precisava ter essa qualificação na cláusula WHERE. Alguém mais nesta questão, disse que a cláusula WHERE é avaliada antes de ORDER BY, assim, a coluna era inexistente quando se avaliou a cláusula WHERE. Indo por esse conselho, eu descobri que uma instrução SELECT aninhada faz o truque:
SELECT * FROM
(SELECT thing.*,
(levenshtein(thing.name, '%s')) AS dist
FROM thing
ORDER BY dist
) items
WHERE dist < (character_length(items.name)/2)
Note que o "itens" alias de tabela é necessária e o alias de coluna dist está acessível no SELECT externa porque é único no comunicado. É um pouco descolada e pouco e eu estou surpreso que ele tem que ser desta maneira em PG -. Mas não parecem ter um impacto na performance por isso estou satisfeito
"foi adicionado porque aparentemente postgres não gosta cláusulas de ordem com campos não selecionados"
"Quanto fim de vai -. Sim, PostgresQL (e muitos outros bancos de dados) não permite ordenação por colunas que não estão listadas na cláusula select"
Simplesmente falso.
=> SELECT id DE ORDEM t1 pelo proprietário LIMIT 5;
id
30 10 20 50 40 (5 linhas)