problema de alias de columna de postgres
-
22-07-2019 - |
Pregunta
Como novato en Postgresql (me estoy mudando porque estoy moviendo mi sitio a heroku que solo lo admite, tengo que refactorizar algunas de mis consultas y código. Aquí hay un problema que no puedo entender entiende el 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 ...
^
... 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 " se agregó porque aparentemente a postgres no le gustan las cláusulas de orden con campos no seleccionados. Pero el error que recibo ahora hace que parezca que tampoco estoy obteniendo alias. ¿Alguien con experiencia en postgres ve el problema?
Es probable que tenga un montón de estos problemas: las consultas funcionaron bien en mySql ...
Solución
En PostgreSQL no puede usar la expresión con un alias en orden por. Solo los alias simples funcionan allí. Su consulta debería verse así:
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;
Supongo que quiere decir que l2.user_id = l.user_id
debería ir primero.
Este es un mensaje relevante en la lista de correo de PostgreSQL-general . Lo siguiente está en la documentación de ORDER BY
cláusula :
Cada expresión puede ser el nombre o número ordinal de una salida columna (elemento de lista SELECCIONAR), o puede ser una expresión arbitraria formada desde valores de columna de entrada .
Entonces no hay alias cuando se usa la expresión.
Otros consejos
Tienes:
order by l2.geopoint_id, l_user_id = l2.user_id desc
en su consulta. Esa es la sintaxis ilegal. Elimine la parte = l2.user_id
(muévala a donde
si esa es una de las condiciones de unión) y debería funcionar.
Actualizar A continuación, seleccionar (con = l2.user_id
eliminado) debería funcionar bien. Lo probé (con diferentes nombres de tabla / columna, obviamente) en 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
Me encontré con este mismo problema usando funciones de fuzzystrmatch, particularmente la función levenshtein. Necesitaba ordenar por la distancia de la cadena y filtrar los resultados por la distancia de la cadena. Originalmente estaba intentando:
SELECT thing.*,
levenshtein(thing.name, '%s') AS dist
FROM thing
WHERE dist < character_length(thing.name)/2
ORDER BY dist
Pero, por supuesto, recibí el error "columna" dist " no existe " de la cláusula WHERE. Intenté esto y funcionó:
SELECT thing.*,
(levenshtein(thing.name, '%s')) AS dist
FROM thing
ORDER BY dist
Pero necesitaba tener esa calificación en la cláusula WHERE. Alguien más en esta pregunta dijo que la cláusula WHERE se evalúa antes de ORDER BY, por lo tanto, la columna no existía cuando evaluaba la cláusula WHERE. Siguiendo ese consejo, descubrí que una declaración SELECT anidada funciona:
SELECT * FROM
(SELECT thing.*,
(levenshtein(thing.name, '%s')) AS dist
FROM thing
ORDER BY dist
) items
WHERE dist < (character_length(items.name)/2)
Tenga en cuenta que los "" elementos " se requiere el alias de tabla y se puede acceder al alias de columna dist en el SELECT externo porque es único en la instrucción. Es un poco raro y me sorprende que tenga que ser así en PG, pero no parece tener un éxito en el rendimiento, así que estoy satisfecho.
" porque aparentemente a postgres no le gustan las cláusulas de orden con campos no seleccionados "
" En lo que respecta al orden, sí, PostgresQL (y muchas otras bases de datos) no permite ordenar por columnas que no están enumeradas en la cláusula select. "
Simplemente falso.
= > SELECCIONE ID DE T1 ORDEN POR EL LÍMITE 5 del propietario;
id
30 10 20 50 40 (5 filas)