sql - 评估每一行的随机函数
问题描述
我有以下sql:
SELECT SERIES.TIME AS TIME
FROM GENERATE_SERIES(
CAST('now' AS TIMESTAMP) - cast('1 month' AS INTERVAL),
CAST('now' AS TIMESTAMP),
CAST('1 day' AS INTERVAL)
) AS SERIES (TIME)
CROSS JOIN
(SELECT * FROM GENERATE_SERIES(1, (floor(random() * 10)::int))) as RANDOM_TABLE
这应该会生成一系列间隔为一小时的日期。我现在试图得到的是每天随机散开。我注意到在上面的 sql 语句random()
中只评估一次,即使它在子查询中。
现在没有CROSS JOIN
我得到:
| 2019-02-13 |
| 2019-02-14 |
| 2019-02-15 |
我现在得到CROSS JOIN
例如:
| 2019-02-13 |
| 2019-02-13 |
| 2019-02-13 |
| 2019-02-14 |
| 2019-02-14 |
| 2019-02-14 |
| 2019-02-15 |
| 2019-02-15 |
| 2019-02-15 |
我想要的是每次扇出时都有一个随机数。例如:
| 2019-02-13 |
| 2019-02-14 |
| 2019-02-14 |
| 2019-02-14 |
| 2019-02-14 |
| 2019-02-15 |
| 2019-02-15 |
| 2019-02-15 |
我如何需要修改我的查询来实现这一点?
解决方案
问题是过早优化。Postgres“忘记”了random()
易变的,每次都应该调用。
这是一个修复:
SELECT SERIES.TIME AS TIME
FROM (SELECT s.time, (floor(random() * 10)::int) as num
FROM GENERATE_SERIES(now() - interval '1 month' , now(), interval '1 day') s(time)
) AS SERIES (TIME)
CROSS JOIN LATERAL
GENERATE_SERIES(1, num) as RANDOM_TABLE
还有一个db<>fiddle。
请注意,我做了一些看起来更像“Postgres”的替换——使用now()
,interval
等等来进行日期算术,而不是转换字符串。
推荐阅读
- c++ - 初始化 C 数组的引用成员不要在 Visual Studio 2015 上编译
- kubernetes - 为数据科学/机器学习任务设置多用户作业调度程序
- javascript - JavaScript 只允许用户点击一次
- awk - 从前 N 个字符中获取唯一值
- ruby-on-rails - Rails 每当 rake 中止!PG::ConnectionBad: fe_sendauth: 未提供密码
- c++ - 不将函数的返回值分配给变量的含义
- .net-core - Dot net core web API url 尝试通过 ajax 调用使用互联网
- c# - C# 反射表达式 Linq
- f# - 在 f# 中从字符串列表的给定路径创建树
- python - 使用装饰器参数进行切换