У більшості баз даних досить зрозуміло про те, що ORDER BY
в підзапиті є або:
- Не дозволено: Наприклад, SQL Server, Sybase SQL Anywhere (якщо не доповнено
TOP
або OFFSET .. FETCH
)
- Безглуздо: Напр. PostgreSQL, DB2 (знову ж таки, якщо не доповнено
OFFSET .. FETCH
або LIMIT
)
Ось приклад із посібника з LUW DB2 (міна акценту)
Пункт 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 не порушать такої поведінки, щоб не зламати майже всю застарілу SQL SQL там, яка ще не перейшла на набагато бажаніші та читаний стандартний OFFSET .. FETCH
синтаксис SQL :
SELECT * FROM table ORDER BY time DESC OFFSET 10 ROWS FETCH NEXT 10 ROWS ONLY