У меня есть канонический топ-N запрос к базе данных Oracle предложил все часто задаваемые вопросы и HowTos:заказать по rownum - это правильно или нет?
select ... from (
select ... from ... order by ...
) where ronwum <= N
Он отлично работает на Oracle 11, то она возвращает топ-N записей в порядке, указанном в внутренний выбор.
Однако он ломается на Oracle 12. Он по-прежнему возвращает одни и те же записи верхнего уровня, но их можно перетасовать. Окончательный порядок этих записей не является детерминированным.
Я googled, но не нашел никаких связанных дискуссий. Похоже, что все остальные всегда получают правильный порядок записи от такого выбора.
Одно открытие было интересным, хотя. Я видел, что некоторые люди используют (без объяснения, к сожалению) дополнительное order by rownum
положения во внешнем выберите:
select ... from (
select ... from ... order by ...
) where ronwum <= N
order by rownum
(как ROWNUM здесь есть ссылки на псевдостолбец Oracle, это не что-то возвращаемое внутреннего выбор)
Он работает, работает. Но с оптимизатором Oracle вы никогда не можете быть уверены, что это просто удача или действительно правильное решение.
Вопрос: order by rownum
Гарантия правильного заказа в этом случае или нет, и почему? Я и мои коллеги не могли договориться об этом.
P.S. Я знаю о других способах выбора записей верхнего уровня, например. используя аналитическую функцию row_number и предложение fetch first
, представленное в Oracle 12. Я также знаю, что я могу повторить то же самое order by ...
на внешнем select. Вопрос только в order by rownum
- это правильно или нет.
Я думаю, что вам нужно переименовать 'rownum' на что-то другое во внутреннем select, иначе внешняя ссылка ссылается на rownum для внешнего запроса, а не на внутренний запрос. –
Правильный способ сделать это - упорядочить по тем же выражениям во внешнем запросе, что и в подзапросе. Даже в Oracle 11 и ранее тот факт, что заказ был сохранен от внутреннего запроса до внешнего, был случайностью реализации - он не гарантируется стандартом SQL. – mathguy