Tengo una consulta SQL simple en PostgreSQL 8.3 que toma muchos comentarios. Proporciono una lista ordenada de valores a la IN
construcción en la WHERE
cláusula:
SELECT * FROM comments WHERE (comments.id IN (1,3,2,4));
Esto devuelve comentarios en un orden arbitrario que, en mi caso, son identificadores 1,2,3,4
.
Quiero que las filas resultantes ordenados como la lista de la IN
construcción: (1,3,2,4)
.
¿Cómo lograr eso?
sql
postgresql
sql-order-by
sql-in
cascanueces
fuente
fuente
Respuestas:
Puede hacerlo con bastante facilidad con (introducido en PostgreSQL 8.2) VALUES (), ().
La sintaxis será así:
fuente
with ordered_products as (select row_number() OVER (ORDER BY whatever) as reportingorder, id from comments) ... ORDER BY reportingorder
.Solo porque es muy difícil de encontrar y tiene que extenderse: en mySQL esto se puede hacer mucho más simple , pero no sé si funciona en otro SQL.
fuente
ERROR: cannot pass more than 100 arguments to a function
En Postgres 9.4 o posterior, esto es probablemente el más simple y rápido :
Usando el nuevo
WITH ORDINALITY
, que @a_horse ya mencionó .No necesitamos una subconsulta, podemos usar la función set-return como una tabla.
Una cadena literal para entregar en la matriz en lugar de un constructor ARRAY puede ser más fácil de implementar con algunos clientes.
Explicación detallada:
fuente
Creo que de esta manera es mejor:
fuente
... order by id=? desc, id=? desc, id=? desc
y parece funcionar bien :-)Con Postgres 9.4 esto se puede hacer un poco más corto:
O un poco más compacto sin una tabla derivada:
Eliminando la necesidad de asignar / mantener manualmente una posición para cada valor.
Con Postgres 9.6 esto se puede hacer usando
array_position()
:El CTE se usa para que la lista de valores solo necesite especificarse una vez. Si eso no es importante, esto también se puede escribir como:
fuente
IN
lista de laWHERE
cláusula nuevamente en laORDER BY
cláusula, lo que hace que esta sea la mejor respuesta en mi humilde opinión ... Ahora solo para encontrar algo similar para MySQL ...order by array_position(array[42,48,43], c.id::int);
que puede provocar errores en algunos casos.array_position(array[42, 48, 43]::bigint[], c.id::bigint)
, por lo que no hay necesidad de truncarbigint
aint
.Otra forma de hacerlo en Postgres sería usar la
idx
función.No olvide crear
idx
primero la función, como se describe aquí: http://wiki.postgresql.org/wiki/Array_Indexfuente
CREATE EXTENSION intarray;
.enable_extension
le permitirá activar esto siempre que el usuario de su aplicación sea miembro delrds_superuser
grupo.En Postgresql:
fuente
position(id::text in '123,345,3,678')
. La identificación3
coincidirá antes que la identificación345
, ¿no?Al investigar esto un poco más, encontré esta solución:
Sin embargo, esto parece bastante detallado y podría tener problemas de rendimiento con grandes conjuntos de datos. ¿Alguien puede comentar sobre estos temas?
fuente
IN
cláusula? porque tengo que hacerlo por miles de registros.Para hacer esto, creo que probablemente debería tener una tabla "ORDEN" adicional que defina el mapeo de ID para ordenar (efectivamente haciendo lo que dice su respuesta a su propia pregunta), que luego puede usar como una columna adicional en su selección entonces puedes ordenar.
De esa manera, usted describe explícitamente el orden que desea en la base de datos, donde debería estar.
fuente
sans SEQUENCE, funciona solo en 8.4:
fuente
o si prefieres el mal al bien:
fuente
Y aquí hay otra solución que funciona y utiliza una tabla constante ( http://www.postgresql.org/docs/8.3/interactive/sql-values.html ):
Pero, una vez más, no estoy seguro de que esto sea efectivo.
Tengo muchas respuestas ahora. ¿Puedo obtener algunas votaciones y comentarios para saber cuál es el ganador!
Gracias a todos :-)
fuente
[EDITAR]
unnest aún no está incorporado en 8.3, pero puede crear uno usted mismo (la belleza de cualquier *):
esa función puede funcionar en cualquier tipo:
fuente
Ligera mejora sobre la versión que usa una secuencia, creo:
fuente
aquí, [bbs] es la tabla principal que tiene un campo llamado ids, y, ids es la matriz que almacena los comentarios.id.
aprobado en postgresql 9.6
fuente
Vamos a tener una impresión visual de lo que ya se dijo. Por ejemplo, tiene una tabla con algunas tareas:
Y desea ordenar la lista de tareas por su estado. El estado es una lista de valores de cadena:
El truco es dar a cada valor de estado un número entero y ordenar la lista numérica:
Lo que lleva a:
Crédito @ user80168
fuente
Estoy de acuerdo con todos los otros carteles que dicen "no hagas eso" o "SQL no es bueno para eso". Si desea ordenar por alguna faceta de comentarios, agregue otra columna entera a una de sus tablas para mantener sus criterios de clasificación y ordenar por ese valor. por ejemplo, "ORDER BY comments.sort DESC" Si desea ordenarlos en un orden diferente cada vez que ... SQL no será para usted en este caso.
fuente