您的问题相当漫长而棘手-不是一个问题。但是,这很有趣,我学到了一些东西。
这个说法是不正确的:
SQL Server为RAND()函数分配一个随机种子:在SELECt中使用时,它仅被种子一次,而不是每一行。
SQL Server具有运行时常量功能的概念。这些是从已编译查询中拉出的函数,并且在查询开始时针对 每个表达式
执行一次。最突出的示例是
getdate()(和相关的日期/时间函数)和
rand()。
如果运行,您可以很容易地看到这一点:
select rand(), rand()from (values (1), (2), (3)) v(x);
每列具有相同的值,但列之间的值不同。
大多数数据库(包括SQLite)对
rand()/都有更直观的解释
random()。(作为个人说明,在每行上返回相同值的“随机”函数非常违反直觉。)每次调用该函数时,您将获得一个不同的值。对于SQL
Server,通常使用使用以下表达式
newid():
select rand(), rand(), rand(checksum(newid()))from (values (1), (2), (3)) v(x);
至于第二个问题, 看来 SQLite实现了递归CTE。所以这就是您想要的:
WITH tbl1(n) AS ( SELECt 1 UNIOn ALL SELECT 2 ), tbl2(n, r) AS ( SELECT n, RANDOM() FROM tbl1 union all select * from tbl2 where 1=0 )SELECt *FROM tbl2 t1 CROSS JOIN tbl2 t2;
我没有看到这种情况的文档,因此使用后果自负。 这是一个DB小提琴。
而且,据记录,这似乎也适用于SQL Server。我刚刚学到了一些东西!
编辑:
正如评论中所建议的,实现可能并不总是发生。它似乎适用于同一级别的两个引用:
WITH tbl1(n) AS ( SELECt 1 UNIOn ALL SELECT 2), tbl2(n, r) AS ( SELECT n, RANDOM() FROM tbl1 union all select * from tbl2 where 1=0 )SELECt t2a.r, count(*)FROM tbl2 t2a left JOIN tbl2 t2b on t2a.r = t2b.rGROUP BY t2a.r;
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)