无限滚动与随机播放结果

时间:2014-05-21 22:20:29

标签: sql sql-server-2008 infinite-scroll

如何返回不重复的随机结果?

例如,我有一个无限滚动的页面,每次我到达底部它会返回十个结果,但有时会重复结果。

我使用此查询获取结果:

SELECT TOP 10 * FROM table_name ORDER BY NEWID()

抱歉,我不知道你是否理解。

2 个答案:

答案 0 :(得分:0)

当您从应用程序调用查询时,您可以为RAND()函数设置种子。

SET @rand = RAND(your_seed); -- initialize RAND with the seed.
SELECT * FROM table_name
ORDER BY RAND() -- Calls to RAND should now be based on the seed
OFFSET 0 LIMIT 10 -- use some MsSQL equivalent here ;) 

(未经测试)

答案 1 :(得分:0)

显然,NEWID()已知分布问题。虽然随机,但数字有时聚集在一起。这将解释你所看到的。你可以试试这个:

SELECT TOP 10 *
FROM table_name
ORDER BY rand(checksum(NEWID()));

这可能会给你带来更好的结果。

但真正的答案是使用种子伪随机数生成器。基本上,枚举表的行并将值存储在表中。或者以确定的方式计算它。然后做简单的数学运算来选择一行:

with t as (
      select t.*, row_number() over (order by id) as seqnum,
             count(*) over () as cnt
      from table_name
     )
select t.*
from t
where mod(seqnum * 74873, cnt) = 13907;

这些数字只是两个素数,可确保缺乏周期。

编辑:

以下是您问题的更完整解决方案:

with t as (
      select t.*, row_number() over (order by id) as seqnum,
             count(*) over () as cnt
      from table_name
     )
select t.*
from t
where mod(seqnum * 74873 + 13907, cnt) <= 10;

或者无论限制是什么。这个想法是,使用一个大的素数作为乘法因子,很可能(但不是100%肯定)那个cnt和&#34; 74783&#34;被称为&#34;互相推理&#34;或者&#34; coprime&#34;。这意味着刚刚描述的伪随机数生成器将重新排列序列号,您可以使用比较来获得一定数量的行。这是数学理论的一部分。