A maioria dos bancos de dados é bastante clara sobre o fato de que uma ORDER BY
subconsulta é:
- Não permitido: por exemplo, SQL Server, Sybase SQL Anywhere (a menos que seja complementado com
TOP
ou OFFSET .. FETCH
)
- Sem sentido: por exemplo, PostgreSQL, DB2 (novamente, a menos que seja complementado com
OFFSET .. FETCH
ou LIMIT
)
Aqui está um exemplo do manual do DB2 LUW (ênfase minha)
Uma cláusula ORDER BY em uma subseleção não afeta a ordem das linhas retornadas por uma consulta. Uma cláusula ORDER BY afeta apenas a ordem das linhas retornadas se for especificada na seleção completa mais externa.
A redação é bastante explícita, assim como no PostgreSQL :
Se a classificação não for escolhida, as linhas serão retornadas em uma ordem não especificada. A ordem real nesse caso dependerá dos tipos de plano de varredura e associação e da ordem no disco, mas não deve ser invocada . Uma ordem de saída específica só pode ser garantida se a etapa de classificação for escolhida explicitamente.
A partir dessa especificação, pode-se concluir que qualquer pedido resultante da ORDER BY
cláusula em uma tabela derivada é meramente acidental e pode coincidir com o pedido esperado (o que ocorre na maioria dos bancos de dados em seu exemplo trivial), mas não seria prudente confiar em isto.
Nota lateral no DB2:
Em particular, o DB2 possui um recurso menos conhecido chamadoORDER BY ORDER OF <table-designator>
, que pode ser usado da seguinte maneira:
SELECT C1 FROM
(SELECT C1 FROM T1
UNION
SELECT C1 FROM T2
ORDER BY C1 ) AS UTABLE
ORDER BY ORDER OF UTABLE
Nesse caso em particular, a ordem da tabela derivada pode ser explicitamente reutilizada na classe SELECT mais externa.
Nota lateral no Oracle:
Durante anos, é uma prática do Oracle implementar a OFFSET
paginação usando ROWNUM
, que só pode ser calculada razoavelmente após o pedido de uma tabela 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
Pode-se razoavelmente esperar que, pelo menos na presença de ROWNUM
uma consulta, as futuras versões do Oracle não quebrem esse comportamento para não quebrar praticamente todo o Oracle SQL herdado, que ainda não migrou para o muito mais desejável e OFFSET .. FETCH
sintaxe padrão legível do SQL :
SELECT * FROM table ORDER BY time DESC OFFSET 10 ROWS FETCH NEXT 10 ROWS ONLY