2016-10-20 2 views
4

Большинство источников, в том числе собственной Top-N Queries статье Oracle, дают синтаксис, подобный следующему для выполнения Top-N запрос:Запрос Oracle Top-N: результаты гарантируются при заказе?

SELECT val 
FROM (
    SELECT val 
    FROM rownum_order_test 
    ORDER BY val DESC 
) 
WHERE ROWNUM <= 5; 

Это гарантированно дать 5 лучших значений; однако, гарантировано ли это в правильном порядке? This question, ссылаясь на Wikipedia, указывает на иное:

Хотя некоторые системы баз данных позволяют спецификацию с ORDER BY в операторе подзапросы или определения представлений, наличие не имеет никакого эффекта.

Означает ли это, что вышеупомянутый код не гарантирует порядок, и требует дополнительной ORDER BY, или это исключительный случай?

SELECT val 
FROM (
    SELECT val 
    FROM rownum_order_test 
    ORDER BY val DESC 
) 
WHERE ROWNUM <= 5 
ORDER BY val; -- Is this line necessary? 

Edit: Предположим, что внешний запрос будет выполняться непосредственно (не вложен в другом запросе). Я задаю этот вопрос, потому что это похоже на вопиющее упущение, что ни один из источников (включая Oracle) не стал упоминать о необходимости для ORDER BY, несмотря на то, что заказы будут интуитивно ожидаться от таких первоклассных запросов.

+1

требуется дополнительный заказ, если вы пытаетесь показать конечный результат в определенном порядке. без него первые 5 строк будут возвращены в случайном порядке, который, как и ожидалось, несколько раз, но не всегда. –

+0

Спасибо @vkp, я так боялся. Хотя я считаю подозрительным, что все источники не обращают внимания на эту важную деталь, учитывая, что интуитивно ожидать, что строки будут возвращены в отсортированном порядке при выполнении запроса top-n. – Douglas

+1

с использованием аналитических функций, таких как 'row_number, rank, dense_rank', даст вам гарантированные результаты. –

ответ

1

Порядок явно проявляется здесь, потому что если бы это не так, запрос просто не работал бы, чтобы обеспечить значения top-n.

Возможно, могут быть случаи, когда оптимизатор может обнаружить, что эффект ORDER BY отсутствует, и в таких случаях он может преобразовать запрос для удаления ORDER BY, но это не один из этих случаев.

Если ваш внешний запрос не переупорядочивает строки, явно или неявно (через объединение, возможно), то я был бы уверен, что в этом случае порядок будет сохранен.

+1

Я бы предпочел то же самое, но я хотел бы найти документацию по этому поведению, прежде чем принять его как окончательный. Многие люди делают одно и то же предположение о заказе словаря 'in.NET, которая, как представляется, сохраняется в большинстве случаев, но затем оказывается (не удерживаться) (https://www.simple-talk.com/blogs/the-net-dictionary/) при определенных обстоятельствах. – Douglas

Смежные вопросы