PostgreSQL技术问答28 - Conditional Expressions
本文是《PostgreSQL技术问答》系列文章中的一篇。关于这个系列的由来,可以参阅开篇文章:
文章的编号只是一个标识,在系列中没有明确的逻辑顺序和意义。读者进行阅读时,不用太关注这个方面。
本文讨论的内容是PostgreSQL中的Conditional Expressions,即条件表达式。
什么是条件表达式
在Postgres中,条件表达式是一类可以直接用在SQL语句中的表达式和函数,用来对字段值和列表进行检查和处理,可以按照某些条件,来进行转换和处理。
我们可以将其简单的理解成为一种可以嵌入在SQL语句中的条件化处理机制。这样,我们就可以在SQL中,在数据库系统内部,进行一些相关数据的批量判断和转换处理,而无需外部实现。
PG中有那些条件表达式
根据官方的技术文档,Postgres中只有以下四个条件表达式,都有对应的语法结构和关键字。
Case
Case这个表达式的完整结构和示例代码如下:
CASE WHEN condition THEN result
[WHEN ...]
[ELSE result]
END
with A(id, name, score, state ) as (values
(1,'关羽', 95, 'H'),
(2,'张飞', 80, 'H'),
(3,'典韦', 75, 'W'),
(4,'陆逊', 60, 'U')
) select name,
case when score >= 85 then '强' when score >= 70 then '中' else '弱' end l,
case state when 'H' then '汉' when 'W' then '魏' else '吴' end n
from A ;
name | l | n
------+----+----
关羽 | 强 | 汉
张飞 | 中 | 汉
典韦 | 中 | 魏
陆逊 | 弱 | 吴
(4 rows)
这里面有几个固定的结构:
- Case 条件判断语句开始
- When 关键字,表示后续内容是一个判断条件
- condition 一个条件判断表达式
- Then 关键字,表示后续内容是条件满足时,就结束表达式并返回后续指定的值
- result contidtion满足时,对应的返回值
- Else 其他情况时的返回值
- End 条件表达式结束
- 返回结果,就是这个条件表达式处理的结果,就是其中一个Then后面那个内容
Case这个表达式,和普通编程语言中的Switch有点类型,但是它会直接返回,没有可选中断所使用break关键字。
示例中我们还可以观察到,其实Case有两种稍有不同的具体形式。默认的形式(case when... then.. else.. end),使用一系列条件判断,可以处理任何条件检查并返回值的情况;还有一种是它的简化方式(case value when a then b else... end ),就是检查某个值,如果匹配则返回对应的值,比较适合做值映射的处理。
COALESCE
coalesce的意思是“合并”。 这是一个函数形式的条件表达式。它接收多个参数,会依次检查这些参数,返回第一个不为null的值。这个方法通常用作对null进行处理的场合,即如果字段内容为null,则返回一个默认值。下面是一个简单的例子:
select coalesce(null, 1), coalesce(2,null,3);
coalesce | coalesce
----------+----------
1 | 2
(1 row)
NULLIF
NULLIF同样是一个函数形式的表达式,它两个参数,如果这两个参数相等,则返回null。否则就返回第一个参数的值。在实际业务中,NULLIF函数一般用于处理特定值或缺失值。下面例举了几种应用情况:
select nullif(1,null), nullif(null,2), nullif(3,3), nullif(3,4);
nullif | nullif | nullif | nullif
--------+--------+--------+--------
1 | | | 3
(1 row)
GREATEST and LEAST
这个很好理解,就是找到值列表中的最大值和最小值,支持文本形式。其标准形式和简单示例如下:
GREATEST(value [, ...])
LEAST(value [, ...])
-- 数组形式
with A (a,b,c) as (values
(1,2,3),
(5,4,3),
(8,9,7)
) select GREATEST(a,b,c), LEAST(a,b,c) from A;
greatest | least
----------+-------
3 | 1
5 | 3
9 | 7
(3 rows)
-- 字符串检查
with A (a,b,c) as (values
('ef','ed','xc')
) select GREATEST(a,b,c), LEAST(a,b,c) from A;
greatest | least
----------+-------
xc | ed
(1 row)
和聚合函数不同,这里的操作是比较字段值之间的大小。而且上面的例子中,数字形式不能和文本放在一起处理,会出现类型的错误。
转载自:https://juejin.cn/post/7387986462866866187