SQL:2023新增聚合特性应该如何使用

胖墨君_4420

胖墨君_4420

2026-08-08

616人浏览

原创

unique nulls distinct 将多个null视为不同值,允许重复插入;nulls not distinct 则视多个null为相同值,违反唯一约束。选型取决于业务需求:允许多个空值时用distinct,要求空值也唯一时用not distinct。

sql:2023新增聚合特性应该如何使用

UNIQUE NULLS DISTINCT 和 NULLS NOT DISTINCT 怎么选

SQL:2023 新增的 UNIQUE NULLS DISTINCT 和 UNIQUE NULLS NOT DISTINCT 是对唯一约束语义的明确化,不是语法糖,而是解决长期存在的空值歧义问题。核心在于:多个 NULL 算不算“重复”。

多数数据库(如 PostgreSQL、SQL Server)默认行为是 NULLS NOT DISTINCT —— 即两个 NULL 被视为相等,插入重复组合会报错 duplicate key violates unique constraint;而 SQLite、MySQL(严格模式下)则倾向将 NULL 视为未知,不参与比较,实际效果接近 NULLS DISTINCT。

  • 显式声明更安全:哪怕你用的是默认行为,也建议写明,避免迁移时语义漂移
  • 业务逻辑决定选型:用户注册表中 (email, phone) 唯一,允许多人留空电话(NULLS DISTINCT);但员工工号+部门组合必须全局唯一,空部门不允许存在(NULLS NOT DISTINCT)
  • 注意 DDL 兼容性:UNIQUE NULLS DISTINCT 在 MySQL 8.0.31+、PostgreSQL 15+、SQL Server 2022+ 支持;旧版本会直接报错 syntax error near NULLS

GROUP BY 中 ORDER BY 引用非分组列是否合法

SQL:2023 的 F868 特性正式允许在 GROUP BY 查询中,ORDER BY 子句引用未出现在 GROUP BY 列表中的确定性表达式(如主键列、函数依赖列),前提是该列在逻辑上被分组键函数决定。

例如:product_id 是 product 表主键,那么 SELECT product_id, SUM(num) FROM product JOIN product_part ... GROUP BY product_id ORDER BY product_name 在 SQL:2023 下合法——因为 product_name 函数依赖于 product_id。

  • 老标准(SQL:2016 及之前)会报错 column "product_name" must appear in the GROUP BY clause or be used in an aggregate function
  • 启用该特性需数据库支持且开启对应模式:PostgreSQL 16+ 默认启用;MySQL 8.0 需设置 sql_mode 包含 ONLY_FULL_GROUP_BY 的反向逻辑(实际仍受限);SQL Server 2022+ 在兼容级别 160+ 下部分支持
  • 别依赖它绕过逻辑设计:如果 product_id 不是主键或存在一对多映射,ORDER BY product_name 仍会出错或结果不确定

聚合函数里怎么安全用 JSON 数据

SQL:2023 新增了 JSON_ARRAYAGG 和 JSON_OBJECTAGG 的增强语义,支持 NULL ON NULL / ABSENT ON NULL 显式控制空值行为,并允许指定排序子句(ORDER BY)直接嵌套在聚合内部。

例如:SELECT department, JSON_OBJECTAGG(name:value ORDER BY salary DESC NULLS LAST) FROM employees GROUP BY department,能按薪资降序生成每个部门的姓名-薪资映射对象。

  • 旧版 JSON_OBJECTAGG(如 PostgreSQL 9.5+、MySQL 5.7+)不支持 ORDER BY,必须先子查询排序再聚合,性能差且易出错
  • NULL ON NULL 是默认行为,生成 {"key": null};ABSENT ON NULL 则跳过整个键值对,避免污染结果
  • 跨数据库移植风险高:SQLite 尚未实现该特性;Oracle 23c 支持但语法略有差异(用 RETURNING 指定类型);务必查目标数据库文档确认支持程度

嵌套分组统计中年/季/月顺序为什么不能颠倒

多级日期分组不是语法问题,而是语义边界问题。GROUP BY YEAR(d), QUARTER(d), MONTH(d) 必须保持年→季→月顺序,否则会出现跨年季度错位(比如把 2023-12 和 2024-01 都归入 Q1)或月份归属错误(如 2023-Q3 里混入 2023-10)。

根本原因是:季度和月份是**相对于年份的偏移量**,不是绝对时间点。单独用 QUARTER(d) 无法区分 2023-Q4 和 2024-Q4;单独用 MONTH(d) 更无法知道属于哪一年的第几季。

  • 必须在 WHERE 中先限定时间范围,再分组:例如 WHERE d >= '2023-01-01' AND d ,否则 <code>GROUP BY 会把所有年份的 Q1 都合并
  • 避免用字符串拼接当分组键:CONCAT(YEAR(d), '-Q', QUARTER(d)) 看似直观,但排序变成字典序(2023-Q10 > 2023-Q2),且丢失数值可计算性
  • PostgreSQL 推荐用 DATE_TRUNC('quarter', d) 作为分组键,MySQL 用 MAKEDATE(YEAR(d), 1) + INTERVAL (QUARTER(d)-1) QUARTER,本质都是还原到季度起点做精确对齐
真正容易被忽略的是:SQL:2023 这些特性大多属于“可选特性”,数据库厂商可以选择不实现,或只实现子集。上线前必须验证目标环境是否真正支持,不能只看文档标题。
PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
数据分析工具有哪些
数据分析工具有哪些

数据分析工具有Excel、SQL、Python、R、Tableau、Power BI、SAS、SPSS和MATLAB等。详细介绍:1、Excel,具有强大的计算和数据处理功能;2、SQL,可以进行数据查询、过滤、排序、聚合等操作;3、Python,拥有丰富的数据分析库;4、R,拥有丰富的统计分析库和图形库;5、Tableau,提供了直观易用的用户界面等等。

2023.10.12

3983

8

SQL中distinct的用法
SQL中distinct的用法

SQL中distinct的语法是“SELECT DISTINCT column1, column2,...,FROM table_name;”。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2023.10.27

851

4

SQL中months_between使用方法
SQL中months_between使用方法

在SQL中,MONTHS_BETWEEN 是一个常见的函数,用于计算两个日期之间的月份差。想了解更多SQL的相关内容,可以阅读本专题下面的文章。

2024.02.23

1029

5

SQL出现5120错误解决方法
SQL出现5120错误解决方法

SQL Server错误5120是由于没有足够的权限来访问或操作指定的数据库或文件引起的。想了解更多sql错误的相关内容,可以阅读本专题下面的文章。

2024.03.06

5841

10

sql procedure语法错误解决方法
sql procedure语法错误解决方法

sql procedure语法错误解决办法:1、仔细检查错误消息;2、检查语法规则;3、检查括号和引号;4、检查变量和参数;5、检查关键字和函数;6、逐步调试;7、参考文档和示例。想了解更多语法错误的相关内容,可以阅读本专题下面的文章。

2024.03.06

2763

4

oracle数据库运行sql方法
oracle数据库运行sql方法

运行sql步骤包括:打开sql plus工具并连接到数据库。在提示符下输入sql语句。按enter键运行该语句。查看结果,错误消息或退出sql plus。想了解更多oracle数据库的相关内容,可以阅读本专题下面的文章。

2024.04.07

5820

11

sql中where的含义
sql中where的含义

sql中where子句用于从表中过滤数据,它基于指定条件选择特定的行。想了解更多where的相关内容,可以阅读本专题下面的文章。

2024.04.29

7741

6

sql中删除表的语句是什么
sql中删除表的语句是什么

sql中用于删除表的语句是drop table。语法为drop table table_name;该语句将永久删除指定表的表和数据。想了解更多sql的相关内容,可以阅读本专题下面的文章。

2024.04.29

1050

5

sql中删除一列的命令是什么
sql中删除一列的命令是什么

在sql中,使用alter table语句可以删除一列,语法为:alter table table_name drop column column_name。想了解更多sql的相关内容,可以阅读本专题下面的文章。

2024.04.29

932

5

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
热门推荐
/
最新课程
phpStudy极速入门视频教程
phpStudy极速入门视频教程

共6课时 | 54.6万人学习

独孤九贱(4)_PHP视频教程
独孤九贱(4)_PHP视频教程

共89课时 | 133.4万人学习