为什么SQLite CTE JOIN中的RANDOM()行为与其他RDBMS不同?

为什么SQLite CTE JOIN中的RANDOM()行为与其他RDBMS不同?,第1张

为什么SQLite CTE JOIN中的RANDOM()行为与其他RDBMS不同?

您的问题相当漫长而棘手-不是一个问题。但是,这很有趣,我学到了一些东西。

这个说法是不正确的:

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;


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5675262.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-16
下一篇 2022-12-16

发表评论

登录后才能评论

评论列表(0条)

保存