Die meisten Datenbanken sind sich ziemlich klar darüber, dass eine ORDER BY
in einer Unterabfrage entweder:
- Nicht erlaubt: zB SQL Server, Sybase SQL Anywhere (sofern nicht mit
TOP
oder ergänzt OFFSET .. FETCH
)
- Sinnlos: zB PostgreSQL, DB2 (wieder, sofern nicht mit
OFFSET .. FETCH
oder ergänzt LIMIT
)
Hier ist ein Beispiel aus dem DB2 LUW-Handbuch (Schwerpunkt Mine)
Eine ORDER BY-Klausel in einer Unterauswahl hat keinen Einfluss auf die Reihenfolge der von einer Abfrage zurückgegebenen Zeilen . Eine ORDER BY-Klausel wirkt sich nur auf die Reihenfolge der zurückgegebenen Zeilen aus, wenn sie in der äußersten vollständigen Auswahl angegeben ist.
Der Wortlaut ist ziemlich explizit, genau wie bei PostgreSQL :
Wenn die Sortierung nicht ausgewählt ist, werden die Zeilen in einer nicht angegebenen Reihenfolge zurückgegeben. Die tatsächliche Reihenfolge hängt in diesem Fall von den Scan- und Join-Planarten und der Reihenfolge auf der Festplatte ab, darf jedoch nicht als zuverlässig angesehen werden . Eine bestimmte Ausgabereihenfolge kann nur garantiert werden, wenn der Sortierschritt explizit ausgewählt wird.
Aus dieser Spezifikation kann geschlossen werden, dass jede Reihenfolge, die sich aus der ORDER BY
Klausel in einer abgeleiteten Tabelle ergibt, nur zufällig ist und zufällig mit Ihrer erwarteten Reihenfolge übereinstimmt (was in den meisten Datenbanken in Ihrem trivialen Beispiel der Fall ist), aber es wäre unklug, sich darauf zu verlassen Dies.
Randnotiz zu DB2:
Insbesondere hat DB2 eine weniger bekannte Funktion namensORDER BY ORDER OF <table-designator>
, die wie folgt verwendet werden kann:
SELECT C1 FROM
(SELECT C1 FROM T1
UNION
SELECT C1 FROM T2
ORDER BY C1 ) AS UTABLE
ORDER BY ORDER OF UTABLE
In diesem speziellen Fall kann die Reihenfolge der abgeleiteten Tabelle im äußersten SELECT explizit wiederverwendet werden
Randnotiz zu Oracle:
In Oracle ist es seit Jahren üblich, die OFFSET
Paginierung mithilfe von zu implementieren ROWNUM
, die nur nach Bestellung einer abgeleiteten Tabelle angemessen berechnet werden kann :
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
Es ist zu erwarten, dass ROWNUM
zukünftige Oracle-Versionen zumindest bei Vorhandensein einer Abfrage dieses Verhalten nicht aufheben, um nicht so ziemlich das gesamte ältere Oracle SQL zu brechen, das noch nicht auf das viel wünschenswertere und umgestiegene Oracle SQL umgestellt wurde lesbare SQL-Standardsyntax OFFSET .. FETCH
:
SELECT * FROM table ORDER BY time DESC OFFSET 10 ROWS FETCH NEXT 10 ROWS ONLY