如何返回不重复的随机结果?
例如,我有一个无限滚动的页面,每次我到达底部它会返回十个结果,但有时会重复结果。
我使用此查询获取结果:
SELECT TOP 10 * FROM table_name ORDER BY NEWID()
抱歉,我不知道你是否理解。
答案 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;。这意味着刚刚描述的伪随机数生成器将重新排列序列号,您可以使用比较来获得一定数量的行。这是数学理论的一部分。