Большинство баз данных совершенно ясно понимают, что ORDER BY
подзапрос - это либо:
- Недопустимо: например, SQL Server, Sybase SQL Anywhere (если не дополнено
TOP
или OFFSET .. FETCH
)
- Бессмысленно: например, PostgreSQL, DB2 (опять же, если не дополнено
OFFSET .. FETCH
или LIMIT
)
Вот пример из руководства по DB2 LUW (выделено мое)
Предложение ORDER BY в подвыборке не влияет на порядок строк, возвращаемых запросом. Предложение ORDER BY влияет только на порядок возвращаемых строк, если оно указано во внешней полной выборке.
Формулировка довольно четкая, как и в PostgreSQL :
Если сортировка не выбрана, строки будут возвращены в неуказанном порядке. Фактический порядок в этом случае будет зависеть от типов планов сканирования и соединения и порядка на диске, но на него нельзя полагаться . Конкретный порядок вывода может быть гарантирован, только если шаг сортировки выбран явно.
Из этой спецификации следует, что любой порядок, полученный в результате ORDER BY
предложения в производной таблице, является просто случайным и может совпадать с вашим ожидаемым порядком (что он делает в большинстве баз данных в вашем тривиальном примере), но было бы неразумно полагаться на это.
Дополнительное примечание по DB2:
В частности, DB2 имеет менее известную функцию под названиемORDER BY ORDER OF <table-designator>
, которая может использоваться следующим образом:
SELECT C1 FROM
(SELECT C1 FROM T1
UNION
SELECT C1 FROM T2
ORDER BY C1 ) AS UTABLE
ORDER BY ORDER OF UTABLE
В этом конкретном случае упорядочение производной таблицы может быть явно использовано повторно во внешнем SELECT
Дополнительное примечание по Oracle:
В течение многих лет в Oracle практикуется использование OFFSET
разбиения на страницы ROWNUM
, которое может быть разумно рассчитано только после заказа производной таблицы:
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
Можно разумно ожидать, что, по крайней мере, при наличии ROWNUM
в запросе будущие версии Oracle не будут нарушать это поведение, чтобы не сломать практически весь существующий Oracle SQL, который еще не перешел на гораздо более желательный и читаемый стандартный OFFSET .. FETCH
синтаксис SQL :
SELECT * FROM table ORDER BY time DESC OFFSET 10 ROWS FETCH NEXT 10 ROWS ONLY