web-dev-qa-db-ja.com

SQL Server UNION-デフォルトのORDER BY動作とは

不自然な例としていくつかのUNIONステートメントがある場合:

SELECT * FROM xxx WHERE z = 1
UNION 
SELECT * FROM xxx WHERE z = 2
UNION
SELECT * FROM xxx WHERE z = 3

デフォルトはorder by振る舞い?

私が見ているテストデータは、基本的に上記で指定された順序でデータを返しません。つまりデータは順序付けされていますが、これに関する優先順位のルールは何か知りたいと思っていました。

もう1つは、この場合xxxがビューであることです。ビューは3つの異なるテーブルを結合して、必要な結果を返します。

37
Ray Booysen

デフォルトの順序はありません。

Order By句がない場合、返される順序は未定義です。つまり、SQL Serverは好きな順序でそれらを戻すことができます。

編集:Order Byなしで見たものに基づいて、結果が返される順序はクエリプランによって異なります。そのため、使用しているインデックスがある場合、結果はこの順序で返される可能性がありますが、保証はありません。

45
DJ.

ORDER BY句の追加に関して:

これはおそらくここのほとんどの初歩的ですが、私はこれを追加すると思った。結果を混合したくない場合があるため、最初のクエリの結果が必要で、次に2番目のクエリのようになります。そのためには、ダミーの最初の列を追加し、それを並べ替えます。ユニオンで列にエイリアスを付けるのを忘れると問題が発生する可能性があるため、通常は序数を列名ではなくorder by句で使用します。

例えば:

SELECT 1, * FROM xxx WHERE z = 'abc'
UNION ALL
SELECT 2, * FROM xxx WHERE z = 'def'
UNION ALL
SELECT 3, * FROM xxx WHERE z = 'ghi'
ORDER BY 1

ダミーの序数列は、2つのクエリを実行し、1つだけが結果を返すことがわかっている場合にも役立ちます。その後、返された結果の序数を確認できます。これにより、複数のデータベース呼び出しやほとんどの空の結果セットチェックを行う必要がなくなります。

15
Will Rickards

実際の答えが見つかりました。

UNIONは重複を削除するため、DISTINCT SORTを実行します。これは、すべてのUNIONステートメントが連結される前に実行されます(実行プランを確認してください)。

並べ替えを停止するには、UNION ALLを実行します。これによって重複が削除されることもありません。

12
Ray Booysen

レコードが返される順序を気にする場合は、順序を使用する必要があります。

省略した場合、(クエリプランで選択されたインデックスに基づいて)整理されて表示される場合がありますが、今日表示される結果は期待した結果とは異なる可能性があります。同じクエリが明日実行されるときにも変更される可能性があります。

編集:いくつかの優れた具体的な例:(すべての例はMS SQLサーバーです)

  • Dave Pinalのブログ は、異なるインデックスが使用されているため、2つの非常に類似したクエリが異なる見かけ上の順序を示す方法を説明しています。

    SELECT ContactID FROM Person.Contact
    SELECT *         FROM Person.Contact
    
  • Conor Cunningham は、テーブルが大きくなると(クエリオプティマイザーが並列実行プランを使用することを決定した場合)、見かけ上の順序がどのように変化するかを示します。

  • Hugo Kornelis は、見かけ上の順序が常に主キーに基づくではないことを証明します。 これは彼のフォローアップ記事です 説明付き。

8
BradC

UNIONは結果セットの順序付けに関して誤解を招く可能性があります。これは、データベースがソート方法を使用して、UNIONで暗黙的なDISTINCTを提供し、行が意図的に順序付けされているように見えるためです-これはUNION ALLには適用されませんもちろん、暗黙の区別はありません。

ただし、10g +でのOracleのハッシュ方式など、順序付けが適用されない、暗黙的な個別のアルゴリズムがあります。

DJが言うように、常にORDER BYを使用してください

2
David Aldridge

テーブルデータが挿入順に返されることを想定して、適切に記述されていないコードに遭遇することは非常に一般的であり、95%の時間、コーダーはそれを回避し、これが多くの一般的なデータベース(MSSQL、Oracle、 MySQL)。もちろん、これは完全な誤りであり、遭遇した場合はalwaysを修正する必要があります。例外なく、必ず自分でOrder By句を使用してください。

1
Cruachan