3

私はSQLServer2008を使用しており、永続層としてNHibernateを使用しています(この問題は純粋にSQLですが、私は信じています)。

問題を次のSQLステートメントに要約しました。

SELECT TOP 2
    this_.Id   as Id36_0_,
    this_.Name as Name36_0_,
    ROW_NUMBER() OVER (ORDER BY this_.IsActive) as MyOrder
FROM    Campsites this_
ORDER BY this_.IsActive  /* a bit field */

これは、ページングされた結果セットを取得するためにNHが生成するクエリの一部です。上記のステートメントは私に次の結果を与えます:

Id36_0_ Name36_0_                       MyOrder
9806    Camping A Cassagnau                 1
8869    Camping a la ferme La Bergamotte    2

ただし、ROW_NUMBER()OVER(ORDER BY this_.IsActive)(NHが最初のページで結果を取得するために生成するもの)を省略すると、結果に2つのまったく異なるテーブルエントリが表示されます。

SELECT   TOP 2
    this_.Id   as Id36_0_,
    this_.Name as Name36_0_
    /* ROW_NUMBER() OVER(ORDER BY this_.IsActive) as MyOrder */
FROM     Campsites this_
ORDER BY this_.IsActive  /* a bit field */

戻り値

Id36_0_ Name36_0_
22876   Centro Vacanze Pra delle Torri
22135   Molecaten Park Napoleon Hoeve

これは私を完全に混乱させ、アプリのバグにつながり、検索の最初のページと2番目のページの最初の要素と同じCampsiteエントリを取得します。

同じORDERBY句がROW_NUMBEROVER()式内で異なる動作をするのはなぜですか?

4

3 に答える 3

5

ORDER BY this_.IsActive/*ビットフィールド*/

これはビットフィールドであるため、0または1のみにすることができます...このビットフィールドが0または1である行が多数あると思いますが、それを並べ替えても意味がありません。90%がアクティブな場合はどうなりますか...その場合、2番目の注文がないため、実際には正しく注文されていません。

ユニークなものを選んでみませんか...たぶんhis_.Nameなど

またはこれはどうですか?

ROW_NUMBER() OVER (ORDER BY this_.IsActive, this_.Name) 
于 2010-06-01T19:21:56.747 に答える
3

ビットフィールドはどの順序にも不適切であるため(SQL Menaceが指摘したように)、どちらの場合も基本的にランダムです。それらは互いに関係がないため、DBエンジンによって個別に評価されます。

ノート:

  • 内部のORDERBYは、ROW_NUMBER()値の順序にのみ適用されます。
  • 出力ORDERBYはthis_.IsActiveのみです
于 2010-06-01T19:22:15.553 に答える
3

結果も名前順に並べられることが期待されますが、ORDERBY句にはIsActiveしかありません。

SELECTの性質はセットベースであるため、順序を明示的に定義しない場合は、クエリの任意の(ただし一見正しい)順序の結果に依存しないでください。

于 2010-06-01T19:26:36.157 に答える