2

次のクエリを検討してください。

SELECT DISTINCT x.*
FROM (
        SELECT DISTINCT Id,
            VideoId,
            [Date],
            NTILE(2) OVER(ORDER BY VideoId) AS tile_nr
        FROM
            [Database].[dbo].[Table] a
     ) x
WHERE
    CONVERT(Date, [Date]) = CONVERT(Date, GETDATE())

ビデオの合計行数は 3320 です。NTILE 関数を使用すると、リストを 2 つの部分に分割できます。したがって、最後に AND を置くと、次のようになります。

AND
    x.tile_nr = 1

結果セットの前半を返します。問題、または問題であると私が信じていることは、ほとんどの場合、最初の結果セットに 1656 レコードが含まれていることです。ただし、1657 レコードを含む場合もあります。そのため、結果セットの後半も取得すると、合計が 3321 になることがあります。どうすればこれを回避できますか?

4

1 に答える 1

1

NTile の BOL エントリを見ると、http://msdn.microsoft.com/en-us/library/ms175126.aspx というコメントが表示されます

パーティション内の行数が integer_expression で割り切れない場合、1 つのメンバーが異なる 2 つのサイズのグループが発生します。OVER 句で指定された順序で、大きなグループが小さなグループの前に置かれます。たとえば、行の総数が 53 で、グループの数が 5 の場合、最初の 3 つのグループには 11 行が含まれ、残りの 2 つのグループにはそれぞれ 10 行が含まれます。一方、行の総数がグループ数で割り切れる場合、行はグループ間で均等に分散されます。たとえば、行の総数が 50 で、5 つのグループがある場合、各バケットには 10 行が含まれます。

そうは言っても、行数は複数の実行間で変化する可能性があり、最終的に異なるグループ/合計になる可能性があるため、結果を一時テーブルに保持する必要がある場合があります。ベース テーブルに戻るのではなく、一時テーブルに戻ると、データが同じであることを保証できます。

于 2013-07-10T13:51:51.667 に答える