暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

PostgreSQL学习实践|随机函数和条件表达式

415


PostgreSQL是一种非常强大的开源关系数据库管理系统,前面已有介绍,可以参考博主其他博文。它提供了一系列的数学函数,以便用户可以执行各种复杂的数学运算。

1 测试环境


当前所有测试均以PostgreSQL 14为蓝本测试,其他版本可能有差异,请酌情参考。

PostgreSQL 14.13 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-44), 64-bit


2 随机函数

在PostgreSQL中,随机函数主要用于生成随机数或随机选择数据,这些函数在多种应用场景中都非常有用,例如在数据测试时产生随机测试数据、随机抽样、排序测试、模拟随机事件(主要应用在数学或者科学)、随机任务分配或者请求测试概率等等。

2.1. RANDOM() - 生成随机数

RANDOM 返回一个 0 到 1 之间的随机浮点数,返回值的范围在 0.0 <= x < 1.0 之间,例如 0.43615015380448896 。当我们的需求是需要0 ~ 10,或者0 ~ 100以内的随机数,可以变换下思维来生成,若是需要整数,则可以直接取整数或者截取整数部分等等。

【语法】

random ( ) → double precision

【示例】

SELECT 
	RANDOM() as val_01,						-- 随机 0 ~ 1 之间的数
	RANDOM() * 10 as val_010,		 	-- 随机 0 ~ 10 之间的数
	RANDOM() * 50 as val_050, 		-- 随机 0 ~ 50 之间的数
	RANDOM() * 100 as val_0100; 	-- 随机 0 ~ 100 之间的数

如果想生成一些测试数据,例如想生成10个在 [1, 100] 范围内的随机整数,可以这样子操作

SELECT floor(random() * 100 + 1) AS random_num  
FROM generate_series(1, 10);

(1)在PostgreSQL 14 的版本中,只有RANDOM()这一个函数,直延续到了PostgreSQL 15。

(2)在PostgreSQL 16中新增了random_normal ( [ mean double precision [, stddev double precision ]] ) → double precision 函数(使用给定参数从正态分布返回一个随机值;平均默认值为0.0,stddev默认值为1.0)

(3)而在PostgreSQL 17 中又扩展了 RANDOM()(PostgreSQL 17 在今年9月份才发布,所以在线的测试工具以及我本地也没有测试环境,有环境的小伙伴可以尝试测试下),新增的扩展功能如下:

# 返回一个随机数,范围在 min <= x <= max
random ( min integer, max integer ) → integer
random ( min bigint, max bigint ) → bigint
random ( min numeric, max numeric ) → numeric


2.2. SETSEED() - 设置随机数种子

设置随机数生成的种子值,用于控制 RANDOM() 的输出。SETSEED() 接受一个 0 到 1 之间的参数。

SELECT SETSEED(0.5); -- 设置随机数种子
SELECT RANDOM(); 

setseed() 的效果通常是会话级或事务级的。如果在同一个会话或事务中多次调用 setseed(),只有最后一次调用设置的种子值会生效。虽然设置种子值对性能的影响很小,但在高频率生成随机数的情况下仍需注意。原文如下:

3 条件处理表达式

3.1 GREATEST() LEAST() - 最大值和最小值

  • GREATEST():返回一组数字中的最大值。
  • LEAST():返回一组数字中的最小值,与GREATEST()相反,可以参考。

【语法】

GREATEST(value [, ...])

LEAST(value [, ...])

【示例】

-- 返回最大(最后)
SELECT 
  -- 返回数据集合中最大的数 20
	GREATEST(10, 20, 5) as max_1,  
  -- 按照字典顺序返回最大
	GREATEST('Oracle', 'MySQL', 'PostgreSQL', 'TiDB', 'YashanDB', 'DMDB') as max_4, 
  -- 返回 '2024-12-26',日期排在最后的
	GREATEST('2024-11-01'::DATE, '2024-10-28'::DATE, '2024-12-26'::DATE),  
	-- NULL将被忽略
  GREATEST(6, 9, NULL) as max_2, 
  -- NULL将被忽略,此时都为NULL,则返回NULL
	GREATEST(NULL, NULL, NULL, NULL, NULL) as max_3; 

注意:GREATESTLEAST不在SQL标准中,而是一个常见的扩展。如果任何参数为NULL,而不仅仅是当所有参数都为NULL时,其他一些数据库会使它们返回NULL。

3.2 CASE() - 万一/具体情况为

SQL中CASE表达式是一个通用条件表达式,类似于其他编程语言中的if/else语句,这是一个在SQL中非常常用的一个函数,相信学习其他SQL系统的并不陌生,多数情况用来处理空值。一般这个有两种写法,如下:

【语法】

-- 语法一(有点类似其他语言中的IF ELSE):
-- 具体情况 当 字段(条件) 然后处理结果
--		……
-- 		或者(上述情况举例完毕) 结果
-- 	结束
CASE WHEN condition THEN result
     [WHEN ...]
     [ELSE result]
END

-- 语法二(有点类似Java语法中的switch语句):
-- 具体情况 字段(条件)
--		当 匹配值
-- 		当 匹配值 ……
-- 		或者(上述情况举例完毕) 结果
-- 	结束
CASE expression
    WHEN value THEN result
    [WHEN ...]
    [ELSE result]
END

具体示例就不在演示,使用情况较多,使用频率较高,希望掌握。

3.3 COALESCE - 处理NULL

COALESCE函数返回其第一个非空参数,仅当所有参数都为空时才返回Null。多数情况用来处理空值。

【语法】

COALESCE(value [, ...])

【示例】

SELECT 
	-- 结果是 Aion 
	COALESCE(NULL, 'Aion', 'modb') as val_1,
	-- 结果是 Aion
	COALESCE(NULL, NULL, 'Aion') as val_2,
	-- 结果是 1
	COALESCE(1, 2, 3);

实际业务中,与 CASE 表达式相比,COALESCE 通常更简洁,特别是在处理多个可能的 NULL 值时。例如我这里,可以这样子写

SELECT COALESCE(t12.ind_unit, '%') AS effective_login FROM t12;

再者,我有一张测试表,想在查询时处理性别(sex)为空的设置为 “-”

SELECT t1.username, COALESCE(t1.sex, '-'), t1.birthday FROM schema_learn.lt_user AS t1;

一般情况,基础使用很少使用,都是应用在SQL查询语句上面,处理空值的情况比较多,而我使用也较少,习惯使用case [when then ……] else end 来处理。

……
SELECT tt.* FROM  (
	select 
		t0.current_year as ind_name, '同比' as ind_type,
		case when t12.ind_yoy is null then 0 else t12.ind_yoy end as ind_value, 
		case when t12.ind_unit is null then '%' else t12.ind_unit end as ind_unit,
		case when t12.p_code is null then '[${p_code}]' else t12.p_code end as p_code
	from t0 left join t12 on t0.current_year = t12.current_year
) as tt 
ORDER BY tt.ind_name ASC

注意:

COALESCE 的参数类型不必相同,但它们必须能够相互兼容或者 PostgreSQL 能够自动将它们转换为一种共同的类型。如果参数类型不兼容,PostgreSQL 会尝试进行类型转换,如果转换失败,则抛出错误。例如

SELECT COALESCE('A', 2, 3);

3.4 NULLIF - 处理NULL

【语法】

NULLIF(value1, value2)

如果value e1等于value e2,则NULLIF函数返回空值;否则返回value e1,例如 NULLIF(1, 2.2)则返回1。这可用于执行上面给出的COALESCE示例的逆运算。

-- 如果性别有 “女”,则返回NULL,其他不变。
SELECT t1.username, NULLIF(t1.sex, '女') as sex, t1.birthday 
FROM schema_learn.lt_user AS t1;

总结

好了,时间不早了,参考原文写到这里,实践得真知,每天学习一点,慢慢来,学习之旅正在路上。



[引用]

  1. 数学函数:https://www.postgresql.org/docs/current/functions-math.html
  2. 条件表达式:https://www.postgresql.org/docs/14/functions-conditional.html
最后修改时间:2024-11-03 20:08:42
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

文章被以下合辑收录

评论