2012-08-10 14 views
8

tengo la siguiente consulta en Postgres:extraño error de pedido (es un error?) En Postgres en el pedido dos columnas con valores idénticos

SELECT * 
FROM "bookings" 
WHERE ("bookings".client_id = 50) 
ORDER BY session_time DESC 
LIMIT 20 OFFSET 0 

El registro en el puesto 20 es tiene un session_time idéntica a la 21 ° registro

Esta consulta arroja 20 resultados, sin embargo, si compara los resultados con toda la base de datos, la consulta arroja los resultados del 1. ° al 19. ° y el 21, omitiendo el 20 °.

Esta consulta se puede fijar mediante la adición de "id" a la orden:

SELECT * 
FROM "bookings" 
WHERE ("bookings".client_id = 50) 
ORDER BY session_time DESC, id 
LIMIT 20 OFFSET 0 

Sin embargo me preguntaba cómo se produjo este error? ¿Cómo se archiva la orden Postgres idéntica cuando se utilizan compensaciones y límites? ¿Es aleatorio? ¿Es un error con postgres?

+4

Si desea resultados deterministas, debe incluir un desempate único en su orden de. Es lo mismo que no tener 'order by' en absoluto y esperar que los resultados se clasifiquen en un orden particular. No hay garantías de que lo harán. –

+3

Lo que te refieres se llama un tipo estable. Una clasificación estable mantiene los registros en el orden original cuando tienen claves coincidentes. Definitivamente no hay requisitos para una clasificación estable en SQL. No dependería de eso en ningún producto. Como sugiere Martin, use otra columna como desempate. –

+6

Esto definitivamente * no * es un error - usted lo pidió solo ordenado por 'session_time', y el planificador le dará el plan más rápido que lo haga; no hace suposiciones sobre qué * else * podría querer ordenar por lo que no indicó. Solo por diversión, actualice una de esas filas (incluso a valores actuales) y haga un 'SELECT' sin una cláusula' ORDER BY'. Si desea cosas en un orden particular, debe especificar eso. – kgrittn

Respuesta

8

Esto no es un error. El límite y la compensación se producen después de realizar el pedido y no es determinante qué filas se seleccionan en un caso frente a otro. En general, desea tener un desempate para que su orden sea estable y determinista (prefiero usar desempates únicos incluso cuando no tengo problemas de límite o compensación para garantizar que la consulta sea la misma cada vez que se ejecuta).

Si está haciendo la paginación, agregue la clave principal o la clave sustituta al tipo como un desempate. Esa es realmente la mejor manera.