SELECT ROW_NUMBER()は、生成された行番号でソートされた結果を返すことが保証されていますか?


10

たとえば、SQLクエリについて考えてみましょう。

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

ここでは、A。[Name]でソートされて返される結果を観察します。ROW_NUMBER関数で定義されたソート列を別の列に変更すると、結果はその列でソートされます。

行番号が行に割り当てられることを期待していましたが、同じ基準で行がソートされて戻ってくるとは思っていませんでした。これは単にクエリがどのように実行されているか(SQL Server 2008 R2の場合)の副作用ですか、それともこの動作は保証されていますか?(私はそのような保証への言及を見つけることができませんでした)。


10
保証はありません。ずっと。SQL Serverに何かを注文する方法を伝えない限り、希望する順序でデータを自由に返すことができます。順序を省略することで、SQL Serverに順序を気にしないように指示しています。保証が必要な場合は、すでにORDER BY句を入力してください。
アーロンバートランド

問題のorder-by句は非常に複雑であるため、コピーするとコードメンテナンスバラストが作成されるだけでなく、将来の欠陥の可能性が高くなるため、尋ねるのには十分な理由があります。もう1つの方法は、SQL標準で暗黙の並べ替え順序が定義されている場合に回避できると思われるマイナーなリファクタリングです。いずれにせよ、この点をカバーする正式な文書があるかどうかだけに興味がありました。
redcalx 2012年

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;

これで、式を1か所で変更するだけで済み、結果の並べ替えはその式に基づくため、繰り返す必要はありません。


6
実際、repeating the complex ORDER BY expression出力がROW_NUMBER()の順序で出力されることさえ保証していません。ORDER BY句の列が一意のキーを形成しない限り。
孔夫子

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し、結果自体で使用 することです。


OKもう1つ条件を追加します。ROW_NUMBER()句が1つだけ指定されている場合、結果は必ずソートされます。
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
これは実際には質問に答えるものではなく、受け入れられた回答と非常に賛成された回答の両方に同意しないようです。
エリックダーリン

私は回答というよりコメントであることに同意します。まあ、受け入れられた答えは実際には答えではありません。ただし、注文を信頼しない方がよいと書かれています-それが問題でした。実際にソートを実行していることが実行プランで確認できます。明示的な順序を追加すると、2番目のソートが取得されます。しかし、それは証拠ではありません。それは経験的知識の一部にすぎません
Eske Rahn

(もちろん、テーブルにアクセスするために使用できる適切なインデックスがない場合にのみソートを実行しますが、明示的に順序を指定することは一般的にコストがかからないことを示すためにのみ追加しました)
Eske Rahn
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.