Oracle Database 19c 新特性之 ANY_VALUE 聚合函数

news/2024/11/7 16:58:08/

ANY_VALUE 函数是 Oracle 19c 新增的一个聚合函数,可以为分组操作之后的每个组返回一个任意值,可以解决查询字段不属于 GROUP BY 字段的问题。

假如我们想要获取每个部门中的员工数量,可以使用 COUNT 函数和 GROUP BY 子句(示例数据):

SELECT d.dept_id, d.dept_name, COUNT(e.emp_id)
FROM department d
LEFT JOIN employee e 
ON e.dept_id = d.dept_id
GROUP BY d.dept_id, d.dept_name;DEPT_ID|DEPT_NAME|COUNT(E.EMP_ID)|
-------+---------+---------------+1|行政管理部|              3|2|人力资源部|              3|3|财务部   |              2|4|研发部   |              9|5|销售部   |              8|6|保卫部   |              0|

我们需要将所有非聚合函数中的字段(d.dept_id 以及 d.dept_name)写在 GROUP BY 子句中,否则查询将会返回错误。例如:

SELECT d.dept_id, d.dept_name, COUNT(e.emp_id)
FROM department d
LEFT JOIN employee e 
ON e.dept_id = d.dept_id
GROUP BY d.dept_id;SQL 错误 [979] [42000]: ORA-00979: 不是 GROUP BY 表达式

在以上查询中,d.dept_name 字段由 d.dept_id 字段唯一决定,逻辑上并不需要出现在 GROUP BY 子句中,但是 SQL 语法上必须这样写。另外,GROUP BY 中的字段会带来额外的性能开销。一个常用的解决方法就是使用 MIN 或者 MAX 函数。例如:

SELECT d.dept_id, MAX(d.dept_name), COUNT(e.emp_id)
FROM department d
LEFT JOIN employee e 
ON e.dept_id = d.dept_id
GROUP BY d.dept_id;DEPT_ID|MAX(D.DEPT_NAME)|COUNT(E.EMP_ID)|
-------+----------------+---------------+1|行政管理部        |              3|2|人力资源部        |              3|3|财务部           |              2|4|研发部           |              9|5|销售部           |              8|6|保卫部           |              0|

这种方法可以避免在 GROUP BY 子句中使用额外的字段,但是新增的 MIN 或者 MAX 函数仍然会带来一定的性能开销。

为了彻底解决这个问题,我们可以使用 ANY_VALUE 聚合函数。该函数的使用方法和 MIN 或者 MAX 相同,但是它的开销更小,因为它会直接返回组内第一个非空的数据。例如:

SELECT d.dept_id, ANY_VALUE(d.dept_name), COUNT(e.emp_id)
FROM department d
LEFT JOIN employee e 
ON e.dept_id = d.dept_id
GROUP BY d.dept_id;DEPT_ID|ANY_VALUE(D.DEPT_NAME)|COUNT(E.EMP_ID)|
-------+----------------------+---------------+1|行政管理部              |              3|2|人力资源部              |              3|3|财务部                 |              2|4|研发部                 |              9|5|销售部                 |              8|6|保卫部                 |              0|

除此之外,当我们想要为每个部门返回一个任意的员工姓名,也可以使用 ANY_VALUE 函数实现:

SELECT d.dept_id, ANY_VALUE(d.dept_name), ANY_VALUE(e.emp_name), COUNT(e.emp_id)
FROM department d
LEFT JOIN employee e 
ON e.dept_id = d.dept_id
GROUP BY d.dept_id;DEPT_ID|ANY_VALUE(D.DEPT_NAME)|ANY_VALUE(E.EMP_NAME)|COUNT(E.EMP_ID)|
-------+----------------------+---------------------+---------------+1|行政管理部              |张飞                  |              3|2|人力资源部              |诸葛亮                |              3|3|财务部                 |孙尚香                |              2|4|研发部                 |赵氏                  |              9|5|销售部                 |法正                  |              8|6|保卫部                 |                     |              0|

使用 ANY_VALUE 函数时,需要注意它是一个不确定性的函数,不确保每次调用都返回相同的结果。

数据量不大的时候 ANY_VALUE 函数性能提升不明显。但是随着数据量的增加,它的性能比 GROUP BY 子句增加字段或者使用 MIN 或者 MAX 函数更好。

使用 MIN 或者 MAX 函数获取任意数据时可能会引起误解,因为它们通常表示获取最小值或者最大值。而使用 ANY_VALUE 函数含义更加明确。

另外,虽然 ANY_VALUE 函数的参数支持 ALL 以及 DISTINCT 关键字,但是它们并不会影响结果。


http://www.ppmy.cn/news/2142.html

相关文章

华为机试真题 Python 实现【积木最远距离】【2022.11 Q4 新题】

目录 题目 思路 考点 Code 题目 小华和小薇一起通过玩积木游戏学习数学。 他们有很多积木,每个积木块上都有一个数字,积木块上的数字可能相同。 小华随机拿一些积木挨着排成一排,请小薇找到这排积木中数字相同且所处位置最远的2块积木块,计算他们的距离,小薇请你帮忙替…

3.20 关于怎样做好小红书直播的一些技巧【玩赚小红书】

一、直播前准备 首先,我们需要知道,与其他直播平台不同,在小红书平台中,直播模块和带货模块是分开的。如果主播想在小红书直播,需要同时申请开通直播权限和带货权限。如果少一个,就不能在小红书平台上带货…

刷爆力扣之最短无序连续子数组

刷爆力扣之最短无序连续子数组 HELLO,各位看官大大好,我是阿呆 🙈🙈🙈 今天阿呆继续记录下力扣刷题过程,收录在专栏算法中 😜😜😜 该专栏按照不同类别标签进行刷题&…

【学习笔记】Python+request+Unittest接口测试入门

PythonrequestUnittest接口测试入门 接口测试流程 1.需求分析(产品经理的需求文档) 2.接口文档解析(开发编写的接口API文档) 3.设计接口测试用例(编写Excel表格形式的用例) 4.准备接口测试脚本&#xff1…

k8s,30分钟部署一个kubernetes集群【1.17】

作者:李振良 官方网站:http://www.ctnrs.com kubeadm是官方社区推出的一个用于快速部署kubernetes集群的工具。 这个工具能通过两条指令完成一个kubernetes集群的部署: # 创建一个 Master 节点 $ kubeadm init# 将一个 Node 节点加入到当前集群中 $ kubeadm join <Mast…

8.论文学习Liver Tumor Segmentation and Classification: A Systematic Review

目录摘要1.引言2.文献调查3.肝脏肿瘤分割的一般步骤A.CT肝脏图像B.图像预处理C.肝脏分割和肿瘤分割D.特征提取E.分类4.肝脏图像预处理方法A.中值滤波B.双边滤波器(BF)C. Wiener滤波器D.导向滤波guided filterE.递归高斯滤波Recursive Gaussian filteringF.Kirsch算子5.肝脏和肿…

【YOLOv7/YOLOv5系列算法改进NO.48】构建新的轻量网络—Slim-neck by GSConv(2022CVPR)

文章目录 前言一、解决问题二、基本原理三、​添加方法四、总结前言 作为当前先进的深度学习目标检测算法YOLOv7,已经集合了大量的trick,但是还是有提高和改进的空间,针对具体应用场景下的检测难点,可以不同的改进方法。此后的系列文章,将重点对YOLOv7的如何改进进行详细…

Allegro如何设置走线禁布区操作指导

Allegro如何设置走线禁布区操作指导 Allegro可以任意设置走线的禁布区,以下图为例,需要在两个pin中间设置一个所有层都不能走线的禁布区域 具体操作如下 选择shape Add Rect命令 Option选择画在Route keepout-All层,type选择Static solid 鼠标移动到器件pad附近,右击会…