关于SQL:2023标准的分类介绍,Peter Eisentraut在这篇文章有详细的示范说明:
https://peter.eisentraut.org/blog/2023/04/04/sql-2023-is-finished-here-is-whats-new
文章对SQL:2023标准进行了分析,并归类了三方面的变化:
- 当前SQL语言的一些小变更
- JSON相关的功能特性
- 新引入图查询的接口
文章围绕这三方面进行了示例说明,同时作者又紧接着分析了PostgreSQL数据库对SQL:2023标准的支持情况,参考文章如下:
https://peter.eisentraut.org/blog/2023/04/18/postgresql-and-sql-2023
SQL:2023标准 | PostgreSQL支持情况 |
---|---|
UNIQUE null treatment (F292) | PostgreSQL 15 |
ORDER BY in grouped table (F868) | ancient |
GREATEST and LEAST (T054) | ancient |
String padding functions (T055) | ancient |
Multi-character TRIM functions (T056) | ancient |
Optional string types maximum length (T081) | ancient |
Enhanced cycle mark values (T133) | PostgreSQL 14 |
ANY_VALUE (T626) | PostgreSQL 16 |
Non-decimal integer literals (T661) | PostgreSQL 16 |
Underscores in numeric literals (T662) | PostgreSQL 16 |
JSON data type (T801) | PostgreSQL 9.2/9.4 |
Enhanced JSON data type (T802) | future |
String-based JSON (T803) | not planned |
Hex integer literals in SQL/JSON path language (T840) | PostgreSQL 16 |
SQL/JSON simplified accessor (T860–T864) | future |
SQL/JSON item methods (T865–T878) | future |
JSON comparison (T879–T882) | PostgreSQL 9.4 |
Property Graph Queries | future |
备注:
- ancient:PostgreSQL 10之前已支持,广泛使用中。
- not planned:社区可能觉得该功能已过时,没有价值做。
- future:未来的版本准备做。
下面简要介绍14~16版本支持的特性
Enhanced cycle mark values (T133)
PostgreSQL 14对递归查询语句增加了两个新特性: SEARCH和CYCLE。
WITH RECURSIVE ... (
SELECT ...
UNION ALL
SELECT ...
)
CYCLE id SET is_cycle USING path;
使用CYCLE选项,用于标记循环,进行检测来避免循环,CYCLE和SEARCH选项可以更灵活控制搜索模式并避免出现死循环问题。
UNIQUE null treatment (F292)
长期以来,在PostgreSQL里NULL空对象是允许重复的,如果使用唯一约束一般同时加上非空约束。这样可以避免插入多个NULL空对象。
但如果允许插入NULL对象,有且仅有一个NULL对象,在15以前可以使用部分表达式索引来实现:
CREATE UNIQUE INDEX ON tab ((column is null)) WHERE column IS NULL;
使用where条件对null值创建了唯一索引并存储为true值。
在PostgreSQL 15里,可以对NULL空对象是否重复进行语法控制:
UNIQUE NULLS DISTINCT UNIQUE NULLS NOT DISTINCT
使用示例如下:
Non-decimal integer literals (T661)
PostgreSQL对字符串常量的形式支持非常丰富,然而对数字类型常量表示形式比较少,PostgreSQL 16实现了十六进制、八进制、二进制形式的整型常量,非十进制的表示形式可以更容易阅读和理解代码。
十进制形式
SELECT 1234;
十六进制形式
SELECT 0x4D2 hex_int;
八进制形式
SELECT 0o2322 oct_int;
二进制形式
SELECT 0b10011010010 bin_int;
Underscores in numeric literals (T662)
PostgreSQL 16可以使用下划线对整型和数字常量进行虚拟分组,示例如下:
用于测试函数
SELECT count(*) FROM generate_series(1, 1_000_000);
用于查询条件
SELECT ... WHERE a > 0 and a < 3.14159_26535_89793/2;
用于更新值
UPDATE ... SET x = 0x_FFFF_FFFF ...
ANY_VALUE (T626)
PostgreSQL 16实现的any_value函数可以对分组后的数据去重只返回单行。
例如下面这张人员表,按部门编号各有两行数据:
postgres=# table person;
┌────────┬─────────────┐
│ deptno │ name │
├────────┼─────────────┤
│ 10 │ dept1_name1 │
│ 10 │ dept1_name2 │
│ 20 │ │
│ 20 │ dept2_name2 │
└────────┴─────────────┘
(4 rows)
查询person表,每个部门获取一位人员,分组查询使用any_value函数,部门编号为10返回上面的第一行数据,部门编号为20跳过空行返回第四行数据。
postgres=# SELECT deptno, any_value(name) FROM person GROUP BY deptno;
deptno | any_value
--------+-------------
10 | dept1_name1
20 | dept2_name2
(2 rows)
使用any_value聚合函数时也可以指定排序,下面按name降序返回数据,部门编号为10返回最上面的第二行数据。
postgres=# SELECT deptno, any_value(name order by name desc)
FROM person
GROUP BY deptno;
deptno | any_value
--------+-------------
10 | dept1_name2
20 | dept2_name2
(2 rows)