2017-03-29 11 views
1

私はCTEを使用して、書籍の著者を販売ランクに基づいてランク付けしています。 ROW_NUMBER()ORDER BYを受け取って、それに基づいて返される行番号を特定できることを理解しています。ROW_NUMBER()は常に外側の結果を並べ替えますか?

私のクエリは次のようになります。

WITH cte (idWork, author, rn) 
AS 
(
    SELECT 
     idWork, 
     authorName, 
     ROW_NUMBER() OVER (PARTITION BY idWork ORDER BY authorSalesRank) 
    FROM dbo.Works_Authors_Works 
    INNER JOIN Authors ON Authors.idAuthor = Works_Authors_Works.idAuthor 
) 
SELECT TOP 100 * FROM cte 

私は結果は予想通りである、このように見えることに気づいた:

+---------+----------------+------+ 
| idWork | author   | rn | 
+---------+----------------+------+ 
| 1  | test1   | 1 | 
| 1  | test2   | 2 | 
| 1  | test3   | 3 | 
| 2  | beep1   | 1 | 
| 2  | beep2   | 2 | 
| 3  | nobody   | 1 | 
+---------+----------------+------+ 

私はこのCTEを持つ2つの質問があります

  • 結果は常にROW_NUMBERフィールドrnでソートされますか?結果がidWorkにグループ化されているように、rnにソートされていますか?たとえば、idWorkが1の場合、行はrn、1,2,3の順にソートされます。これは偶然の一致か、それともいつものようなものでしょうか?
  • SELECT TOP 1 * FROM cte WHERE idWork = 1を実行すると、常にrn = 1の行が返されますか?

実行計画では、入力ソートはidWorkauthorSalesRankです。これらは、外側の結果がこれでもソートされていることを暗示していますか?

execution plan execution plan - sort details

+1

CTEから選択して注文することなく、結果は不確定な順序で戻ってくる可能性があります。 – xQbert

+0

他のRow_Number()以上(オーダーby author desc)がある場合、どのオーダーを先にするかを保証することはできません。実行計画では、 'ordered'は真ではありません –

+0

実行計画が添付されており、パイプラインのある時点で注文されたようです。 –

答えて

3

あなたはそれを明示的に注文する必要があります。何の順序が指定されていない場合

WITH cte (idWork, author, rn) AS (
    SELECT 
     idWork, 
     authorName, 
     ROW_NUMBER() OVER (PARTITION BY idWork ORDER BY authorSalesRank) AS rn 
    FROM dbo.Works_Authors_Works 
    INNER JOIN Authors ON Authors.idAuthor = Works_Authors_Works.idAuthor 
) 
SELECT TOP 100 * 
FROM cte 
order by idWork, rn 

SQL(すべてのデータベース)は、それが、それは「常に働く」のようは、あなたがその事例証拠に頼るべきではないと思われる場合でも、順序を保証するものではありません。

+0

優秀な点:順序は決してw/o順序で保証されませんが、通常は演奏中のインデックスによって順序づけされます。これはクエリプランによって異なる場合があります。 – Clay

+0

@Clayはい、データベースがキャッシュされた結果を返すときなどに変更できます。パフォーマンスのために任意の順序でキャッシング/返される可能性があります – Bohemian

関連する問題