PostgreSQL 17: 生成指定范围内的随机数

John Doe 五月 8, 2025

你是否曾想获取 1 到 10 之间的随机整数,却因在 PostgreSQL 中编写的代码略显晦涩而有些烦恼?PostgreSQL 17 的随机函数让这变得更简单。

一头与 SQL 共舞的大象

特性提交日志

添加在指定范围内生成随机数的函数。

本次新增了random()函数的 3 种变体:

  • random(min integer, max integer) returns integer
  • random(min bigint, max bigint) returns bigint
  • random(min numeric, max numeric) returns numeric

每个函数都会返回一个在min <= x <= max范围内的随机数x

对于numeric类型的函数,小数点后的位数等于minmax中小数点后位数较多的那个数的小数位数。

这些函数的主要入口点位于一个新的 C 源文件中。现有的random()random_normal()setseed()函数也被移到了那里,这样它们就可以共享相同的伪随机数生成器(PRNG)状态,该状态在该文件中是私有的。

讨论:https://postgr.es/m/CAEZATCV89Vxuq93xQdmc0t-0Y2zeeNQTdsjbmV7dyFBPykbV4Q@mail.gmail.com

示例

之前的随机函数

random()函数在很长一段时间里基本没什么变化。以前,如果你需要一个随机数,能使用的只有random()这一个函数,它不带参数,返回一个双精度浮点数,取值范围是大等于 0 且小于 1。你什么时候会需要一个大等于 0 且小于 1 的随机双精度数呢?可能从来都不需要,但它确实为完成实际任务提供了有用的基础。那么在 PostgreSQL 17 之前,如何生成 1 到 10 之间的随机整数呢?

在 PostgreSQL 17 之前,一种方法是:

SELECT (1 + random()*10)::integer

在 PostgreSQL 16 中,我们又有了另一个随机函数家族的成员random_normal,要完全理解这个函数,需要具备统计学相关的专业知识才行。

新的随机函数

在 PostgreSQL 17 中,我们有了一种非常直观且简洁的方法,来解决 80% 情况下我们最初使用随机函数想要解决的问题。比如返回 1 到 10 之间的整数:

SELECT random(1,10);

这段代码不仅更简短,意图也更清晰。

假设你想生成随机金额的话,这可能还不够。在很多国家,货币只保留两位小数。那么如何生成 1 到 10 美元之间的随机金额呢?

在 PostgreSQL 17 之前,你会这样做:

SELECT (1 + random()*10)::numeric(4,2);

在 PostgreSQL 17 中,你可以这样写:

SELECT random(1.00,10.00);

它会返回像 5.79 这样的数字,并且始终精确到两位小数。如果两个数字的小数位数不同,它会返回小数位数最多的那个数字的小数位数。例如:

SELECT random(1.00, 10.000);

会返回像 9.657 这样的数字。

确实很棒,非常感谢所有社区的相关人员。

参考

提交日志:https://git.postgresql.org/pg/commitdiff/e6341323a8da64b18e9af3e75a4578230702d61c