Гарантируется ли, что SELECT ROW_NUMBER () возвращает результаты, отсортированные по сгенерированным номерам строк?

10

Например, рассмотрим запрос SQL:

SELECT
   A.[Name],
   ROW_NUMBER() OVER(ORDER BY A.[Name] ASC)
FROM
   [FooTable] AS A

Здесь я наблюдаю результаты, отсортированные по A. [Имя]. Если я изменю столбец сортировки, определенный в функции ROW_NUMBER, на другой столбец, результаты снова будут отсортированы по этому столбцу.

Я ожидал, что номер строки будет присвоен строкам, но я не ожидал, что строки будут возвращены отсортированными по тем же критериям. Является ли это просто побочным эффектом выполнения запроса (в моем случае на SQL Server 2008 R2) или такое поведение гарантировано? (Я не мог найти ссылку на такую ​​гарантию).

redcalx
источник
10
Там нет никакой гарантии. Когда-либо. Если вы не скажете SQL Server, как заказать что-либо, вы можете свободно возвращать данные в любом порядке. Оставляя заказ на, вы сообщаете SQL Server, что вам нет дела до заказа. Если вы хотите получить гарантию, просто введите предложение ORDER BY.
Аарон Бертран
Есть веская причина спрашивать, так как рассматриваемое предложение order-by очень сложное, и поэтому копирование создает как балласт обслуживания кода, так и увеличивает вероятность будущих дефектов. Другой альтернативой является незначительный рефакторинг, который, как я думал, я мог бы избежать, если бы стандарт SQL определял неявный порядок сортировки. В любом случае, мне было просто интересно, была ли официальная документация по этому вопросу.
Redcalx
1
так почему бы не задать этот вопрос?
Аарон Бертран

Ответы:

14

Если вы задали вопрос, я думаю, что вы на самом деле хотели спросить:

Как я могу заказать, ROW_NUMBER()не повторяя сложное ORDER BYвыражение?

Мы могли бы попросить вас создать псевдоним для ROW_NUMBER()выражения, а затем отсортировать, используя псевдоним:

SELECT
   A.[Name],
   rn = ROW_NUMBER() OVER (ORDER BY <complex expression>)
FROM
   dbo.[FooTable] AS A
ORDER BY rn;

Теперь вам нужно всего лишь изменить выражение в одном месте, и результирующая сортировка будет основана на этом выражении без повторения.

Аарон Бертран
источник
6
На самом деле, repeating the complex ORDER BY expressionдаже не гарантирует, что результат будет получен в порядке ROW_NUMBER (). Если столбцы в предложении ORDER BY не образуют уникальный ключ.
2012 г.
22

Точно нет. Доказательство:

SELECT
   A.[Name],
   ROW_NUMBER() OVER(ORDER BY A.[Name] ASC),
   ROW_NUMBER() OVER(ORDER BY A.[Name] DESC)
FROM
   [FooTable] AS A

Единственный способ гарантировать заказ в SQL - это запросить его, использовать ORDER BYсам результат.

Ремус Русану
источник
Хорошо, я добавлю еще одну квалификацию - гарантированно сортируются ли результаты, если указано только одно предложение ROW_NUMBER ().
Redcalx
22
Единственный способ гарантировать заказ в SQL - это запросить его
Remus Rusanu
0

На самом деле (старый) вопрос можно расширить, включив в него также разделение по частям, поскольку, как представляется, существует неявный порядок сначала по разделам, а затем по частям

Так что это не так просто, как некоторые предлагали, чтобы назначить row_number и использовать его для упорядочивания.

Нам понадобится также вложенный sql, извлекающий раздел с помощью предложения (если мы, конечно, не хотим просто повторять его)

Эмпирически мы, кажется, получаем последнюю строку порядка неявно

Select
  <field-list>, 
  rn=Row_Number() over(partition by <PartionClause>) order by <OrderClause>
from ....
Order by <PartionClause> asc, rn asc

Но нам не хватает каких-либо доказательств или гарантии того, что это всегда так.

(Если в игре несколько вызовов Row_Number (), это последний, который, кажется, дает порядок)

ТАКЖЕ ВНИМАНИЕ, если вы явно добавляете порядок в плане выполнения, ясно показывает окончательный шаг сортировки, а сортировка уже отсортированного набора является наихудшим случаем, следовательно, с Order By требуется значительно больше времени, чем без

Эске Ран
источник
1
Это на самом деле не отвечает на вопрос, и, кажется, не согласен как с принятым ответом, так и с высоко оцененным ответом.
Эрик Дарлинг
Я согласен, что мой - больше комментарий, чем ответ. Ну, принятый ответ на самом деле не является ответом, за исключением того, что он говорит, что нам лучше не доверять порядку - и это был вопрос. По плану выполнения видно, что он на самом деле выполняет сортировку, и если мы добавим явный порядок, мы получим вторую сортировку. Но это не доказательство, это только часть эмпирического знания
Эске Ран
(Конечно, он выполняет сортировку только в том случае, если нет подходящего индекса, который он может использовать для доступа к таблице, но только добавил его, чтобы показать, что обычно не нужно бесплатно явно отдавать заказ)
Эске Ран