Większość baz danych jest dość jasna na temat faktu, że ORDER BY
w podzapytaniu jest albo:
- Niedozwolone: np. SQL Server, Sybase SQL Anywhere (chyba że uzupełnione o
TOP
lub OFFSET .. FETCH
)
- Bez znaczenia: np. PostgreSQL, DB2 (ponownie, chyba że uzupełnione o
OFFSET .. FETCH
lub LIMIT
)
Oto przykład z podręcznika DB2 LUW (wyróżnienie moje)
Klauzula ORDER BY w podselekcji nie wpływa na kolejność wierszy zwracanych przez zapytanie. Klauzula ORDER BY wpływa tylko na kolejność zwracanych wierszy, jeśli jest określona w skrajnie pełnym wyborze.
Sformułowanie jest dość wyraźne, podobnie jak PostgreSQL :
Jeśli sortowanie nie zostanie wybrane, wiersze zostaną zwrócone w nieokreślonej kolejności. Rzeczywista kolejność w takim przypadku będzie zależeć od typu skanowania i planu dołączania oraz kolejności na dysku, ale nie można na nim polegać . Szczególne uporządkowanie wyjściowe może być zagwarantowane tylko wtedy, gdy zostanie wyraźnie wybrany krok sortowania.
Z tej specyfikacji można ORDER BY
wywnioskować, że każde uporządkowanie wynikające z klauzuli w tabeli pochodnej jest jedynie przypadkowe i może przypadkowo pasować do oczekiwanej kolejności (co robi w większości baz danych w trywialnym przykładzie), ale nierozsądne byłoby polegać na to.
Uwaga dodatkowa na temat DB2:
W szczególności DB2 ma mniej znaną funkcję o nazwieORDER BY ORDER OF <table-designator>
, której można użyć w następujący sposób:
SELECT C1 FROM
(SELECT C1 FROM T1
UNION
SELECT C1 FROM T2
ORDER BY C1 ) AS UTABLE
ORDER BY ORDER OF UTABLE
W tym konkretnym przypadku kolejność tabeli pochodnej może zostać ponownie wyraźnie użyta w najbardziej zewnętrznym SELECT
Uwaga dodatkowa na temat Oracle:
Od lat praktyką w Oracle jest stosowanie OFFSET
paginacji przy użyciu ROWNUM
, którą można racjonalnie obliczyć dopiero po zamówieniu tabeli pochodnej:
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
Można zasadnie oczekiwać, że przynajmniej w obecności ROWNUM
zapytania przyszłe wersje Oracle nie złamią tego zachowania, aby nie złamać prawie całej dotychczasowej wersji Oracle SQL, która nie została jeszcze przeniesiona do znacznie bardziej pożądanej i czytelna standardowa OFFSET .. FETCH
składnia SQL :
SELECT * FROM table ORDER BY time DESC OFFSET 10 ROWS FETCH NEXT 10 ROWS ONLY