random() 函数可以用于生成一个大于等于 0 小于等于 1 的随机数,生成的数据遵循平均分布。不过在实际环境中,更多的数据则是遵循正态分布。PostgreSQL 提供了一个扩展模块 tablefunc,可以用于生成遵循正态分布的随机数;或者我们也可以创建存储函数来模拟正态分布的随机数。
考虑到它的实用性,PostgreSQL 16 新增了一个内置的 random_normal() 函数,用于生成这种随机数。我们使用该函数生成 10 个随机数:
select random_normal() as v from generate_series(1, 10);v |-------------------+ 1.9147182783615317|-1.7265731892046994|-0.9601043210986459| -1.481551351102244|-1.3763031483133177|0.11872324455736474| 0.9016843380853512| 0.1288806844184827|-1.6392171916791691|0.33770959079074697|
默认参数调用时,random_normal() 函数生成的随机数遵循标准正态分布(均值为 0,标准差为 1)。
以下示例生成的随机数遵循均值为 1、标准差为 5 的正态分布:
select random_normal(1, 5) as v from generate_series(1, 10);v |-------------------+-0.4529440542028027| 5.442251124798599| 6.307851828542196| 4.122825670258253| -2.186242122101672| 4.767936509571358| 5.172144288566877| -3.761475521327373|-2.6431751259304193|0.19249449162595722|
接下来我们验证一下该函数生成的数据是否遵循正态分布。
SELECT round(random_normal(1, 0.5)::numeric, 1) AS v, count(*), repeat('#', (count(*) / 100)::integer)FROM generate_series(1, 100000)GROUP BY vORDER BY v;v |count|repeat |----+-----+-------------------------------------------------------------------------------+-1.2| 1| |-1.1| 1| |-1.0| 3| |-0.9| 9| |-0.8| 17| |-0.7| 21| |-0.6| 55| |-0.5| 98| |-0.4| 132|# |-0.3| 248|## |-0.2| 521|##### |-0.1| 728|####### | 0.0| 1090|########## | 0.1| 1586|############### | 0.2| 2203|###################### | 0.3| 2975|############################# | 0.4| 3878|###################################### | 0.5| 4840|################################################ | 0.6| 5778|######################################################### | 0.7| 6670|################################################################## | 0.8| 7299|######################################################################## | 0.9| 7720|############################################################################# | 1.0| 7960|###############################################################################| 1.1| 7794|############################################################################# | 1.2| 7271|######################################################################## | 1.3| 6745|################################################################### | 1.4| 5796|######################################################### | 1.5| 4796|############################################### | 1.6| 3904|####################################### | 1.7| 3034|############################## | 1.8| 2300|####################### | 1.9| 1567|############### | 2.0| 1175|########### | 2.1| 710|####### | 2.2| 454|#### | 2.3| 267|## | 2.4| 164|# | 2.5| 94| | 2.6| 56| | 2.7| 23| | 2.8| 7| | 2.9| 8| | 3.0| 2| |
从上面的图形可以看出,函数返回的结果是一个正态分布。我们还可以进一步通过均值和标准差进行验证:
WITH RECURSIVE d(n, v) AS ( SELECT 1 AS n, random_normal(1, 0.5) AS v UNION ALL SELECT n+1, 0.5) FROM d WHERE n<100000)SELECT count(*), avg(v), stddev(v)FROM d;count |avg |stddev |------+------------------+-------------------+100000|1.0009116232651825|0.49890904328727353|
原文地址:https://tonydong.blog.csdn.net
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。