【发布时间】:2018-05-11 09:46:04
【问题描述】:
公用表表达式 (CTE) 连接中的RANDOM() 值的行为与SQLite 中的预期不同。
SQL:
WITH
tbl1(n) AS (SELECT 1 UNION ALL SELECT 2),
tbl2(n, r) AS (SELECT n, RANDOM() FROM tbl1)
SELECT * FROM tbl2 t1 CROSS JOIN tbl2 t2;
示例 SQLite 结果:
n r n r
1 7058971975145008000 1 8874103142384122000
1 1383551786055205600 2 8456124381892735000
2 2646187515714600000 1 7558324128446983000
2 -1529979429149869800 2 7003770339419606000
每一列的随机数都是不同的。但是CROSS JOIN 重复行 - 所以我希望每列中有 2 对相同的数字 - 是 PostgreSQL、Oracle 11g 和 SQL Server 2014 的情况(使用行时 -基于种子)。
PostgreSQL / Oracle 11g / SQL Server 2014 结果示例:
n r n r
1 0.117551110684872 1 0.117551110684872
1 0.117551110684872 2 0.221985165029764
2 0.221985165029764 1 0.117551110684872
2 0.221985165029764 2 0.221985165029764
问题
- 能否解释 SQLite 中的行为?是错误吗?
- 有没有办法让 CTE 中的表 B(基于同一 CTE 中的表 A)增加一列随机生成的数字,在
JOIN中使用时保持固定?
【问题讨论】:
-
我不确定你的意思是什么。 SQLite 和 SQL Server 是 2 个完全不同的 RDBMS。应该预料到两者之间的不同行为;它们的行为不会完全一样。
-
当然可以,但为什么我们在结果中看不到相同的随机数对?
-
根据 SQL Server documentation:具有相同种子值的 RAND() 重复调用返回相同的结果。 在整个查询中返回相同的数字是为了意料之中。
-
但是没有指定种子值,所以我希望它们都不同:如果没有指定种子,SQL Server 数据库引擎会随机分配一个种子值。
-
在 SQL Server 中,一些非确定性函数,例如 RAND() 和 GETDATE() 每次查询只计算一次,也就是说,它们不会随着查询而改变它们的值在跑。如果你想要 SQL Server 中的“随机性”,可以使用 NEWID(),例如 SORT BY NEWID()
标签: sql sqlite random common-table-expression