为什么在 case 语句中调用 random() 会产生意外的结果



https://gist.github.com/anonymous/2463d5a8ee2849a6e1f5

查询 1 不会产生预期的结果。但是,查询 2 和 3 会这样做。为什么将调用移动到 case 语句之外的 random() 很重要?

考虑第一个表达式:

select (case when round(random()*999999) + 1 between 000001 and 400000 then 1
             when round(random()*999999) + 1 between 400001 and 999998 then 2
             when round(random()*999999) + 1 between 999999 and 999999 then 3
             else 4
        end)
from generate_series(1, 8000000)

大概,您认为值"4"几乎不应该被选中。 但是,问题在于每个when子句都单独调用random()

因此,它失败每个子句的可能性是独立的:

  • 大约 60% 的情况下,随机数不会与"1"匹配。
  • 大约 40% 的情况下,随机数与"2"不匹配。
  • 大约 99.9999% 的情况下,随机数与"3"不匹配(如果 9 的数量关闭,我深表歉意,但值实际上是 1)。

这意味着大约 24% 的时间 (60% * 40% * 99.9999%) 会出现值"4"。 实际上,第一个查询返回"4"的概率为 23.98%。 老实说,这非常接近实际值,但考虑到这种数据大小,但它比我预期的要远一些。 但是,它足以解释正在发生的事情。

最新更新