Sql 迭代cte中的随机值
使用SQL Server 2016+ 我在从一个表中选择随机行时遇到了一些困难,这个表被缩小为一个如何生成随机数的问题。为了提高效率,使用NEWID的前10个*订单会降低速度。在下面的代码中,我使用了一个可重复结果的种子集,但在live中我不会这样做 代码示例:Sql 迭代cte中的随机值,sql,sql-server,random,common-table-expression,Sql,Sql Server,Random,Common Table Expression,使用SQL Server 2016+ 我在从一个表中选择随机行时遇到了一些困难,这个表被缩小为一个如何生成随机数的问题。为了提高效率,使用NEWID的前10个*订单会降低速度。在下面的代码中,我使用了一个可重复结果的种子集,但在live中我不会这样做 代码示例: SELECT RAND(100) RN , RAND() , RAND() , RAND() , RAND(); SELECT RAND(100) RN UNION ALL SELE
SELECT RAND(100) RN
, RAND()
, RAND()
, RAND()
, RAND();
SELECT RAND(100) RN
UNION ALL SELECT RAND()
UNION ALL SELECT RAND()
UNION ALL SELECT RAND()
UNION ALL SELECT RAND();
WITH cte AS
(SELECT 1 ID
, RAND(100) RN
UNION ALL
SELECT cte.ID + 1
, RAND()
FROM cte
WHERE ID < 5)
SELECT RN
FROM cte;
正如您可以从结果中看到的,当我在线或通过联合重复调用RAND函数时,每次调用都会得到不同的结果。然而,如果我在迭代cte中调用函数,那么我会重复得到相同的值
此代码是显示问题的示例,而不是整个代码集。我创建此示例纯粹是为了演示这个问题。我有一个基于Checksum&NewID和模调用以及乘法的组合的解决方案,可以给我想要的范围内的值,但是这相当复杂,而且对于仅仅生成一个范围内的随机数列表来说似乎太过分了
我正在寻找任何可以提供的指导
为什么会这样
有什么办法解决这个问题吗
用于生成非RBAR的随机数列表的其他选项
非常感谢。兰德在查询中返回一个常量值。也就是说,在查询中,每次提及都会对其进行一次评估
如果运行以下命令,您可以看到:
select rand(), rand()
from (values (1), (2), (3)) v(x);
每行有两个不同的值。但是,这些列具有相同的值
在任何情况下,标准答案都是使用RANDCHECKSUMNEWID。这在每次调用时为RAND提供一个随机种子:
WITH cte AS
(SELECT 1 as ID, RAND(CHECKSUM(NEWID())) as RN
UNION ALL
SELECT cte.ID + 1, RAND(CHECKSUM(NEWID())) as RN
FROM cte
WHERE ID < 5
)
SELECT RN
FROM cte;
这可能足以获得一个随机值列表。我怀疑您真正的问题是不同的——类似于从表中提取随机行。如果这是真正的问题,请提出一个新问题或检查类似问题。-根据SQL Server上的其他一些建议,有时每个SQL语句只计算一次函数-例如,您将看到GetDate的相同效果,它不会在任何查询上递增,无论选择记录花费多长时间-如您所说,NewId没有展示这一点,所以它可以满足你的需要。我相信,这背后的部分原因是绩效,谢谢大家。我已经看到了这些类型的解决方案。ORDERBY NewID在大型表上变得非常低效,我现有的解决方法是基于映射到一行的NewID的绝对校验和。这些都是很好的帖子,我相信如果他们登陆这里,他们会帮助其他人。>>生成非RBAR随机数列表的其他选项-从某处下载数百万位数的pi,并将其放入带有id的表格中,然后你需要做的就是生成一个随机id作为种子,然后你可以取下面的pi数字-newid本身是不是效率低下,或者只是排序的代价?回答不错,我很欣赏这些例子
WITH cte AS
(SELECT 1 as ID, RAND(CHECKSUM(NEWID())) as RN
UNION ALL
SELECT cte.ID + 1, RAND(CHECKSUM(NEWID())) as RN
FROM cte
WHERE ID < 5
)
SELECT RN
FROM cte;