La mayoría de las bases de datos son bastante claras sobre el hecho de que un ORDER BY
en una subconsulta es:
- No permitido: por ejemplo, SQL Server, Sybase SQL Anywhere (a menos que se complemente con
TOP
o OFFSET .. FETCH
)
- Sin sentido: por ejemplo, PostgreSQL, DB2 (de nuevo, a menos que se complemente con
OFFSET .. FETCH
o LIMIT
)
Aquí hay un ejemplo del manual de DB2 LUW (énfasis mío)
Una cláusula ORDER BY en una subselección no afecta el orden de las filas devueltas por una consulta. Una cláusula ORDER BY solo afecta el orden de las filas devueltas si se especifica en la selección completa más externa.
La redacción es bastante explícita, al igual que PostgreSQL :
Si no se elige la ordenación, las filas se devolverán en un orden no especificado. El orden real en ese caso dependerá de los tipos de plan de escaneo y unión y el orden en el disco, pero no se debe confiar en él . Un pedido de salida particular solo puede garantizarse si el paso de clasificación se elige explícitamente.
A partir de esta especificación, se puede seguir que cualquier orden resultante de la ORDER BY
cláusula en una tabla derivada es meramente accidental y puede coincidir coincidentemente con su orden esperado (lo que hace en la mayoría de las bases de datos en su ejemplo trivial), pero sería imprudente confiar en esta.
Nota al margen sobre DB2:
En particular, DB2 tiene una característica menos conocida llamadaORDER BY ORDER OF <table-designator>
, que se puede utilizar de la siguiente manera:
SELECT C1 FROM
(SELECT C1 FROM T1
UNION
SELECT C1 FROM T2
ORDER BY C1 ) AS UTABLE
ORDER BY ORDER OF UTABLE
En este caso particular, el orden de la tabla derivada se puede reutilizar explícitamente en el exterior más SELECCIONAR
Nota al margen sobre Oracle:
Durante años ha sido una práctica en Oracle implementar el OFFSET
uso de la paginación ROWNUM
, que puede calcularse razonablemente solo después de ordenar una tabla derivada:
SELECT *
FROM (
SELECT rownum AS rn, t.* -- ROWNUM here depends on the derived table's ordering
FROM (
SELECT * FROM table ORDER BY time DESC
) t
) t
WHERE rn BETWEEN 10 AND 20
Se puede esperar razonablemente que, al menos en presencia de ROWNUM
una consulta, las futuras versiones de Oracle no rompan este comportamiento para no romper casi todo el Oracle SQL heredado que aún no se ha migrado a los más deseables y deseados. OFFSET .. FETCH
sintaxis estándar de SQL legible :
SELECT * FROM table ORDER BY time DESC OFFSET 10 ROWS FETCH NEXT 10 ROWS ONLY