La maggior parte dei database è abbastanza chiara sul fatto che ORDER BY
in una sottoquery sia:
- Non consentito: ad esempio SQL Server, Sybase SQL Anywhere (a meno che non sia integrato con
TOP
o OFFSET .. FETCH
)
- Senza significato: ad esempio PostgreSQL, DB2 (di nuovo, a meno che non sia integrato con
OFFSET .. FETCH
o LIMIT
)
Ecco un esempio dal manuale DB2 LUW (l'enfasi è mia)
Una clausola ORDER BY in una sottoselezione non influisce sull'ordine delle righe restituite da una query. Una clausola ORDER BY ha effetto solo sull'ordine delle righe restituite se è specificata nella fullselect più esterna.
La formulazione è abbastanza esplicita, proprio come PostgreSQL :
Se non viene scelto l'ordinamento, le righe verranno restituite in un ordine non specificato. L'ordine effettivo in quel caso dipenderà dalla scansione e dai tipi di piano di join e dall'ordine su disco, ma non deve essere invocato . Un particolare ordinamento di output può essere garantito solo se la fase di ordinamento viene scelta esplicitamente.
Da questa specifica, si può seguire che qualsiasi ordinamento risultante dalla ORDER BY
clausola in una tabella derivata è semplicemente accidentale e potrebbe coincidere casualmente con il tuo ordinamento previsto (cosa che fa nella maggior parte dei database nel tuo banale esempio), ma non sarebbe saggio fare affidamento su Questo.
Nota a margine su DB2:
In particolare, DB2 ha una funzione meno nota chiamataORDER BY ORDER OF <table-designator>
, che può essere utilizzata come segue:
SELECT C1 FROM
(SELECT C1 FROM T1
UNION
SELECT C1 FROM T2
ORDER BY C1 ) AS UTABLE
ORDER BY ORDER OF UTABLE
In questo caso particolare, l'ordinamento della tabella derivata può essere riutilizzato esplicitamente nella parte più esterna di SELECT
Nota a margine su Oracle:
Per anni è stata una pratica in Oracle implementare l' OFFSET
impaginazione utilizzando ROWNUM
, che può essere ragionevolmente calcolato solo dopo aver ordinato una tabella derivata:
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
Ci si può ragionevolmente aspettare che, almeno in presenza di ROWNUM
una query, le future versioni di Oracle non interrompano questo comportamento al fine di non interrompere praticamente tutto il precedente SQL Oracle esistente, che non è ancora migrato verso il molto più desiderabile e OFFSET .. FETCH
sintassi standard SQL leggibile :
SELECT * FROM table ORDER BY time DESC OFFSET 10 ROWS FETCH NEXT 10 ROWS ONLY