PostgreSQL里有非常丰富的系统功能函数,本文着重介绍一些与开发相关的系统函数。
1.xmltable函数
XMLTABLE是SQL/XML标准定义构造XML格式数据的函数,允许将XML格式数据当成TABLE一样与其它数据表进行关联查询,并且该函数对XML数据的处理解析比客户端处理性能更高。
下面构造一个简单的XML类型数据表,作为数据源进行演示。
create table test_people as select xml $$ <people> <person> <first_name>Pavel</first_name> <last_name>Feng</last_name> <nick>john</nick> </person> <person> <first_name>Jerome</first_name> <last_name>Peng</last_name> </person> </people> $$ as xml_data;
然后我们对XML数据按照TABLE方式进行列查询:
select decoded.* from test_people, xmltable( '//people/person' passing xml_data columns first_name text, last_name text, nick text ) as decoded;
上面语句查询结果如下:
first_name | last_name | nick ------------+-----------+------ Pavel | Feng | john Jerome | Peng | (2 rows)
我们可以对XML数据里的节点名进行重命名:
select decoded.* from test_people, xmltable( '//people/person' passing xml_data columns first_name text, last_name text, nick_name text path 'nick' ) as decoded;
查询结果如下,返回表字段时nick映射为nick_name:
first_name | last_name | nick_name ------------+-----------+----------- Pavel | Feng | john Jerome | Peng | (2 rows)
同时也可以对缺失的子节点项设置默认值:
select decoded.* from test_people, xmltable( '//people/person' passing xml_data columns first_name text, last_name text, nick text DEFAULT '---' ) as decoded;
查询结果如下:nick节点缺失时使用默认值“—”替代。
first_name | last_name | nick ------------+-----------+------ Pavel | Feng | john Jerome | Peng | --- (2 rows)
也可以对结果集添加首列行号:
select decoded.* from test_people, xmltable( '//people/person' passing xml_data columns id for ordinality, first_name text, last_name text, nick text DEFAULT '---' ) as decoded;
查询结果如下:id列为添加的数据行号
id | first_name | last_name | nick ----+------------+-----------+------ 1 | Pavel | Feng | john 2 | Jerome | Peng | --- (2 rows)
还可以使用XPATH函数进行处理,比如组合first_name与last_name:
select decoded.* from test_people, xmltable( '//people/person' passing xml_data columns id for ordinality, full_name text PATH 'concat(first_name, " ", last_name)', nick text DEFAULT '---' ) as decoded;
查询结果如下:使用concat函数对first_name与last_name进行组合。
id | full_name | nick ----+-------------+------ 1 | Pavel Feng | john 2 | Jerome Peng | --- (2 rows)
2.SQL/JSON path函数
JSON path是与开发人员高度相关性的一个特性,PostgreSQL提供了大量的新功能函数来更快捷地解析JSON类型。
SQL/JSON path 函数表达式使用了JavaScript的一些语法,如下:
SQL/JSON path 函数表达式的变量,如下:
创建以下测试表并插入一条 JSON测试数据,准备如下:
CREATE TABLE T_JSONPATH (a jsonb);
INSERT INTO T_JSONPATH (a) VALUES ('
{ "gpsname": "postgres",
"track" :
{
"segments" : [
{ "location": [ 49.773, 15.2104 ],
"start time": "2020-05-11 10:05:14",
"HR": 73
},
{ "location": [ 49.776, 15.4125 ],
"start time": "2020-06-21 10:39:21",
"HR": 130
} ]
}
}');
如果通过JSON操作符查询JSON数据元素值,如下:
postgres=# SELECT a ->> 'gpsname' FROM T_JSONPATH; ?column? ---------- postgres (1 row)
使用SQL/JSON path函数表达式进行查询
postgres=# SELECT jsonb_path_query(a,'$.gpsname') FROM T_JSONPATH; jsonb_path_query ------------------ "postgres" (1 row)
jsonb_path_query函数是JSON path最常用函数。
如果JSON数据涉及较多层级,这时JSON path的函数表达式就更加易用,比如查询表T_JSONPATH的track.segments下一层级的元素。
postgres=# SELECT jsonb_path_query(a,'$.track.segments[1].HR') FROM T_JSONPATH; jsonb_path_query ------------------ 130 (1 row)
除此之外,还可使用jsonb_path_exists函数判断是否存在指定Json路径,语法如下:
postgres=# SELECT jsonb_path_exists(a,'$.track.segments.HR') FROM T_JSONPATH; jsonb_path_exists ------------------- t (1 row)
3.正则表达式函数
PostgreSQL目前支持多种POSIX风格的正则表达式函数。
4.UUID函数
PostgreSQL 13之前不提供生成UUID的内置函数,如果需要使用UUID数据类型,需要加载外部uuid_ossp或pgcrypto扩展,才能生成UUID数据。从PostgreSQL 13开始可以直接使用系统函数gen_random_uuid()函数,示例如下:
postgres=# SELECT gen_random_uuid(); gen_random_uuid -------------------------------------- 960d6103-090e-472e-901e-daac7b73a3a3 (1 row)
PostgreSQL的主键策略也推荐阅读如下两篇文章:
5.string_to_table函数
string_to_table函数可以对将字符串按分隔符拆分为数据行,它与string_to_array函数类似,等价于unnest(string_to_array()),并且性能也更好。
示例如下:
postgres=# select string_to_table('foo,bar,baz',',');
string_to_table
-----------------
foo
bar
baz
(3 rows)
第一个参数为待拆分的字符串,如果第二个参数分隔符为NULL,则字符串的每个字符将作为独立的一行,如下:
postgres=# select string_to_table('abcdefg',null);
string_to_table
-----------------
a
b
c
d
e
f
g
(7 rows)
如果分隔符为空串,则整个字符串将作为一行,如下:
postgres=# select string_to_table('abcdefg','');
string_to_table
-----------------
abcdefg
(1 row)
如果第三个参数不为NULL,则匹配的子串将替换为NULL,如下:
postgres=# select string_to_table('ab,cd,ef,gh',',','cd');
string_to_table
-----------------
ab
ef
gh
(4 rows)
注意string_to_table函数不适用于解析CSV格式字符串,如下:
postgres=# select string_to_table('foo,bar,baz,"baz,boo"',',');
string_to_table
-----------------
foo
bar
baz
"baz
boo"
(5 rows)
6.date_bin函数
date_bin函数可以将指定的时间戳强制截断到最接近指定时间间隔的开头。date_bin函数功能类似date_trunc,但date_bin函数可以截断为任意时间间隔,不要求间隔只能是一个时间单位。
date_trunc函数按时间单位进行截断的示例如下:
postgres=# select 'untruncated' as spec, now()
union all
select spec, date_trunc(spec, now())
from string_to_table('microseconds,milliseconds,second,minute,hour,day,week,month,quarter,year,decade,century,millennium',',') as u(spec);
spec | now
--------------+-------------------------------
untruncated | 2022-12-08 15:25:30.891473+08
microseconds | 2022-12-08 15:25:30.891473+08
milliseconds | 2022-12-08 15:25:30.891+08
second | 2022-12-08 15:25:30+08
minute | 2022-12-08 15:25:00+08
hour | 2022-12-08 15:00:00+08
day | 2022-12-08 00:00:00+08
week | 2022-12-05 00:00:00+08
month | 2022-12-01 00:00:00+08
quarter | 2022-10-01 00:00:00+08
year | 2022-01-01 00:00:00+08
decade | 2020-01-01 00:00:00+08
century | 2001-01-01 00:00:00+08
millennium | 2001-01-01 00:00:00+08
(14 rows)
date_bin函数的示例如下:
postgres=# select date_bin('15 minutes', timestamp '2021-05-12 13:41:23', timestamp '2001-01-01');
date_bin
---------------------
2021-05-12 13:30:00
(1 row)
date_bin函数的第一个参数为时间间隔,例如15 minutes(minutes也可简写为min或m)表示以15分钟为间隔,间隔有四个时间点:0分钟、15分钟、30分钟和45分钟。
date_bin函数的第二个参数为要处理的时间戳,第三个参数如果有时间部分,则时间部分将作为偏移量添加到结果的时间部分。
postgres=# select date_bin('15 minutes', timestamp '2021-05-12 13:41:23', timestamp '2001-01-01 00:05:01');
date_bin
---------------------
2021-05-12 13:35:01
(1 row)
按间隔截断的2021-05-12 13:30:00将添加一个偏移量05:01,结果是:2021-05-12 13:35:01。
其实还有大量与开发相关的函数并未介绍全,例如丰富的窗口函数、数学函数(最大公约数gcd函数,最小公倍数lcm函数,阶乘factorial函数)等。
最后推荐下面这个网址,方便进行函数检索及示例学习
https://www.sqliz.com/postgresql-ref
保持联系
本人组建了一个技术交流群:PG乐知乐享交流群。欢迎关注文章的小伙伴随缘加入,进群请加本人微信skypkmoon并备注PG乐知乐享。
编辑推荐:
- PostgreSQL标识列及存储列示例03-14
- PostgreSQL易用的开发函数03-14
- PostgreSQL运行时角色连接及角色查询问题03-14
- PostgreSQL自定义快捷命令03-14
- Unnest函数的几个小特性03-14
- PostgreSQL 15可靠性之统一非排他性备份模式03-14
- PostgreSQL超级用户下放的权限03-14
- 请不要固步自封,升级到 PostgreSQL 16 的 7 大理由!03-14
相关推荐
-
雷神推出 MIX PRO II 迷你主机:基于 Ultra 200H,玻璃上盖 + ARGB 灯效
2 月 9 日消息,雷神 (THUNDEROBOT) 现已宣布推出基于英
-
制造商 Musnap 推出彩色墨水屏电纸书 Ocean C:支持手写笔、第三方安卓应用
2 月 10 日消息,制造商 Musnap 现已在海外推出一款 Oce
热文推荐
- PostgreSQL 15可靠性之统一非排他性备份模式
PostgreSQL 15可靠性之统一非排他性备份模式
26-03-14 - 请不要固步自封,升级到 PostgreSQL 16 的 7 大理由!
请不要固步自封,升级到 PostgreSQL 16 的 7 大理由!
26-03-14 - PostgreSQL千万数据量下的DDL变更影响
PostgreSQL千万数据量下的DDL变更影响
26-03-14 - 致敬PostgreSQL 11退役 |巴音布鲁克永远的干!
致敬PostgreSQL 11退役 |巴音布鲁克永远的干!
26-03-14 - 换一种角度理解PostgreSQL的search_path
换一种角度理解PostgreSQL的search_path
26-03-14 - 系统明天上线,PG表空间还不规划好疯狂给同事埋雷
系统明天上线,PG表空间还不规划好疯狂给同事埋雷
26-03-14 - 时序数据库TimescaleDB是站在了PG的肩膀上?扒了扒了
时序数据库TimescaleDB是站在了PG的肩膀上?扒了扒了
26-03-14 - RockyLinux使用shutdown命令安全关闭系统(新手必看:详解Linux安全关机操作)
- 向量数据库PGVECTOR,AI浪潮下崛起的新秀!
向量数据库PGVECTOR,AI浪潮下崛起的新秀!
26-03-14 - 聊聊pg_bulkload的大概的实现逻辑
聊聊pg_bulkload的大概的实现逻辑
26-03-14
