Чи гарантовано SELECT ROW_NUMBER () для повернення результатів, відсортованих за генерованими номерами рядків?


10

Наприклад, врахуйте запит SQL:

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

Тут я спостерігаю за результатами повернення, відсортованими за А. [Ім'я]. Якщо я зміню стовпчик сортування, визначений у функції ROW_NUMBER, на інший стовпець, то знову результати будуть відсортовані за цим стовпцем.

Я очікував, що номер рядка буде присвоєний рядкам, але я не очікував повернення рядків, відсортованих за тими самими критеріями. Це просто побічний ефект від того, як виконується запит (у моєму випадку на SQL Server 2008 R2), або це поведінка гарантована? (Я не можу знайти посилання на таку гарантію).


10
Ніколи не існує жодної гарантії. Колись. Якщо ви не скажете SQL Server, як замовити щось, безкоштовно повертайте дані в будь-якому порядку. Виходячи з замовлення на, ви говорите SQL Server, що вам не байдуже. Якщо ви хочете отримати гарантію, просто введіть пункт «ЗАМОВИТИ ЗА».
Аарон Бертран

Існує вагома причина для запитання, оскільки питання про порядок замовлення дуже складне, тому копіювання створює як баласт технічного обслуговування коду, так і збільшує ймовірність майбутніх дефектів. Інша альтернатива - це незначний рефакторинг, якого, я думав, мені вдасться уникнути, якщо стандарт 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 (). Якщо стовпці в пункті ЗАМОВЛЕННЯ ДО не утворюють унікальний ключ.
孔夫子

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 - це попросити його
Рем Русану

0

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

Отже, це не так просто, як деякі пропонують, як призначити номер_ рядка та використовувати його для замовлення.

Нам також знадобиться вкладений 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
Це насправді не відповідає на питання, і, здається, не погоджується як з прийнятою відповіддю, так і з високо обґрунтованою відповіддю.
Ерік Дарлінг

Я згоден, що моє - це скоріше коментар, ніж відповідь. Ну прийнята відповідь насправді не є відповіддю, за винятком того, що вона говорить, що нам краще не довіряти наказу - і саме до цього було питання. План виконання може бачити, що він фактично робить сортування, і якщо ми додамо явне замовлення до, ми отримуємо другий сорт. Але це НЕ доказ, це лише частина емпіричних знань
Еске Ран

(Зрозуміло, це лише сортування, якщо немає відповідного індексу, який він може використовувати для доступу до таблиці, але лише додав його, щоб показати, що це, як правило, безкоштовно явно давати замовлення від)
Eske Rahn
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.