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 功能,我可以将列表分为两部分。因此,当我像这样在末尾加上 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 整除,这将导致两个大小的组相差一个成员。较大的组按照 OVER 子句指定的顺序排在较小的组之前。例如,如果总行数为 53,组数为 5,则前三个组将有 11 行,其余两个组将各有 10 行。另一方面,如果总行数可被组数整除,则行将均匀分布在各组中。例如,如果总行数为 50,并且有五个组,则每个存储桶将包含 10 行。

话虽如此,您可能必须将结果保存在临时表中,因为行数可能会在多次执行之间发生变化,并且您最终可能会得到不同的组/总数。如果您返回临时表而不是返回基表,则可以保证数据是相同的。

于 2013-07-10T13:51:51.667 回答