oracle 中的开窗函数over()

2023-11-20

开窗函数与聚合函数一样,都是对行的集合组进行聚合计算。它用于为行定义一个窗口(这里的窗口是指运算将要操作的行的集合),它对一组值进行操作,不需要使用GROUP BY子句对数据进行分组,能够在同一行中同时返回基础行的列和聚合列。反正我理解这个函数已经使用好子查询或者是其它方式求得聚合列的值给我合并。

以书中的例子一步一步来介绍,假设要计算所有人员的总数,我们可以执行下面的SQL语句:

SELECT COUNT(FName) FROM T_Person

这种方式比较直接,只返回一个聚合列的值,没有任何基础行的列的值。但是有时需要从不在聚合函数中的行的列中访问这些聚合计算的值(即基础行的列)。比如我们想查询每个工资小于5000元的员工信息(城市以及年龄),并且在每行中都显示所有工资小于5000 元的员工个数,尝试编写下面的SQL语句:

SELECT FName, FCITY, FAGE, FSalary, COUNT(FName)
FROM T_Person
WHERE FSALARY<5000

执行上面的SQL以后我们会得到下面的错误信息
选择列表中的列'T_Person.FCity' 无效,因为该列没有包含在聚合函数或GROUP BY 子句中。
这是因为所有不包含在聚合函数中的列必须声明在GROUP BY 子句中,使用子查询的方式是可以解决:

SELECT FName, FCITY, FAGE, FSalary,
(
SELECT COUNT(FName) FROM T_Person
WHERE FSALARY<5000
)
FROM T_Person
WHERE FSALARY<5000

虽然使用子查询能够解决这个问题,但是子查询的使用非常麻烦,使用开窗函数则可以大大简化实现,下面的SQL语句展示了如果使用开窗函数来实现同样的效果:

SELECT FName, FCITY, FAGE, FSalary, COUNT(FName) OVER()
FROM T_Person
WHERE FSALARY<5000

可以看到与聚合函数不同的是,开窗函数在聚合函数后增加了一个OVER关键字。
开窗函数的调用格式为:函数名(列) OVER(选项)

我这里使用的是SQL Server 2008 R2,不知道从什么时候开始,SQL SERVER也支持开窗函数中使用ORDER BY子句(注:书本中说MSSQLServer中是不支持开窗函数中使用ORDER BY子句)。不管怎么样,这里我整合了网上的相关内容。也正因为开窗函数支持了ORDER BY子句之后,开窗函数被分为两大类。

第一大类:聚合开窗函数====》聚合函数(列) OVER (选项),这里的选项可以是PARTITION BY子句,但不可是ORDER BY子句

第二大类:排序开窗函数====》排序函数(列) OVER(选项),这里的选项可以是ORDER BY子句,也可以是 OVER(PARTITION BY子句 ORDER BY子句),但不可以是PARTITION BY子句


聚合开窗函数

 

OVER 关键字表示把聚合函数当成聚合开窗函数而不是聚合函数。SQL 标准允许将所有聚合函数用做聚合开窗函数。
在上边的例子中,开窗函数COUNT(*) OVER()对于查询结果的每一行都返回所有符合条件的行的条数。OVER关键字后的括号中还经常添加选项用以改变进行聚合运算的窗口范围。如果OVER关键字后的括号中的选项为空,则开窗函数会对结果集中的所有行进行聚合运算。

PARTITION BY 子句

 

开窗函数的OVER关键字后括号中的可以使用PARTITION BY 子句来定义行的分区来供进行聚合计算。与GROUP BY 子句不同,PARTITION BY 子句创建的分区是独立于结果集的,创建的分区只是供进行聚合计算的,而且不同的开窗函数所创建的分区也不互相影响。下面的SQL语句用于显示每一个人员的信息以及所属城市的人员数:

SELECT FName, FCITY, FAGE, FSalary,
COUNT(FName) OVER(PARTITION BY FCITY)
FROM T_Person

OVER(PARTITION BY FCITY)表示对结果集按照FCITY进行分区,并且计算当前行所属的组的聚合计算结果。在同一个SELECT语句中可以同时使用多个开窗函数,而且这些开窗函数并不会相互干扰。比如下面的SQL语句用于显示每一个人员的信息、所属城市的人员数以及同龄人的人数:

SELECT FName,FCITY, FAGE, FSalary,
COUNT(FName) OVER(PARTITION BY FCITY),
COUNT(FName) OVER(PARTITION BY FAGE)
FROM T_Person

 

排序开窗函数

 

对于排序开窗函数来讲,它支持的开窗函数分别为:ROW_NUMBER(行号)、RANK(排名)、DENSE_RANK(密集排名)和NTILE(分组排名)。

先看一段SQL语句:

select  FName, FSalary, FCity, FAge,  
row_number() over(order by FSalary) as rownum,  
rank() over(order by FSalary) as rank,  
dense_rank() over(order by FSalary) as dense_rank,  
ntile(6) over(order by FSalary)as ntile 
from  T_Person 
order by  FName  

 执行的结果如下(对于想自己尝试的朋友,那你得辛苦点,下载电子书或者是购买书来学习吧。因为我可是限于篇幅,省略去大部分内容哦):

 

看到上面的结果了吧,下面来介绍下相关的内容。我们得到的最终结果是按照FName进行升序显示的。

对于row_number() over(order by FSalary) as rownum来说,这个排序开窗函数是按FSalary升序的方式来排序,并得出排序结果的序号

对于rank() over(order by FSalary) as rank来说,这个排序形容函数是按FSalary升序的方式来排序,并得出排序结果的排名号。这个函数求出来的排名结果可以排列,并列排名之后的排名将是并列的排名加上并列数(简单说每个人只有一种排名,然后出现两个并列第一名的情况,这时候排在两个第一名后面的人将是第三名,也就是没有了第二名,但是有两个第一名)

对于dense_rank() over(order by FSalary) as dense_rank来说,这个排序函数是按FSalary升序的方式来排序,并得出排序结果的排名号。这个函数与rand()函数不同在于,并列排名之后的排名只是并列排名加1(简单说每个人只有一种排名,然后出现两个并列第一名的情况,这时候排在两个第一名后面的人将是第二名,也就是两个第一名,一个第二名)

对于ntile(6) over(order by FSalary)as ntile 来说,这个排序函数是按FSalary升序的方式来排序,然后6等分成6个组吗,并显示所在组的序号。

排序函数和聚合开窗函数类似,也支持在OVER子句中使用PARTITION BY语句。例如:

select  FName, FSalary, FCity, FAge,  
row_number() over(partition by FName  order by FSalary) as rownum,  
rank() over(partition by FName order by FSalary) as rank,  
dense_rank() over(partition by FName order by FSalary) as dense_rank,  
ntile(6) over(partition by FName order by FSalary)as ntile 
from  T_Person 
order by  FName

 关于PARTITION BY子句,请看上面的介绍,这里就不再累赘了。但是需要注意一点的是,在排序开窗函数中使用PARTITION BY子句需要放置在ORDER BY子句之前。


总结:

over()开窗函数: 在使用聚合函数后,会将多行变成一行,
而开窗函数是将一行变成多行;
并且在使用聚合函数后,如果要显示其他的列必须将列加入到group by中,
而使用开窗函数后,可以不使用group by,直接将所有信息显示出来。

开窗函数适用于在每一行的最后一列添加聚合函数的结果。

常用开窗函数:
1.为每条数据显示聚合信息.(聚合函数() over())
2.为每条数据提供分组的聚合函数结果(聚合函数() over(partition by 字段) as 别名) --按照字段分组,分组后进行计算
3.与排名函数一起使用(row number() over(order by 字段) as 别名)

常用分析函数:(最常用的应该是1.2.3 的排序)
1、row_number() over(partition by ... order by ...)
2、rank() over(partition by ... order by ...)
3、dense_rank() over(partition by ... order by ...)
4、count() over(partition by ... order by ...)
5、max() over(partition by ... order by ...)
6、min() over(partition by ... order by ...)
7、sum() over(partition by ... order by ...)
8、avg() over(partition by ... order by ...)
9、first_value() over(partition by ... order by ...)
10、last_value() over(partition by ... order by ...)
11、lag() over(partition by ... order by ...)
12、lead() over(partition by ... order by ...)
lag 和lead 可以 获取结果集中,按一定排序所排列的当前行的上下相邻若干offset 的某个行的某个列(不用结果集的自关联);
lag ,lead 分别是向前,向后;
lag 和lead 有三个参数,第一个参数是列名,第二个参数是偏移的offset,第三个参数是 超出记录窗口时的默认值)


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

oracle 中的开窗函数over() 的相关文章

  • oracle查看表空间大小

    查看表空间大小 select a tablespace name a bytes 1024 1024 Sum MB a bytes b bytes 1024 1024 used MB b bytes 1024 1024 free MB ro
  • Oracle数据库预警信息阈值设置以及预警信息自动邮件发送到管理员邮箱

    当数据库处于不理想状态时 默认情况下会通过EM发出预警 也可以通过邮件发送给管理员 要设置电子邮件通知 可在EM上 1任何 Database Control 页中 单击页眉和页脚区中的 Setup 设置 链接 2 在 Setup 设置 页中
  • 数据库 对于索引的理解

    今天 看了下oracle数据库的索引 我一直不理解索引的机制到底是什么 正好看到了一篇博客 对理解索引有一定的好处 参考文献 https www cnblogs com java learner p 9567456 html
  • 7.Oracle19c RAC集群安装部署

    1 Oracle 19c RAC For Linux安装部署 https edu csdn net course detail 35792 2 Oracle数据库 底层原理解析 解析oracle数据库内部实现 详细讲解了Oracle数据库内
  • 报错:ORA-00955:名称已由现有对象使用

    报错 ORA 00955 名称已由现有对象使用 查下名称看看 是不是已经有视图或者表存在 我遇到的是确实存在了 可能已经创建成功了 或者用个不一样的名称
  • oracle PL/SQL小结

    PL SQL 代码块 DECLARE optional BEGIN required EXCEPTION optional END required 若使用dbms output输出时 先要设置 set serveroutput on 显示
  • Oracle自动工作量资料档案库(AWR)和自动数据库诊断监视器(ADDM)基础知识

    OracleDB内置的AWR存放一些快照 这些快照的内容是重要的统计信息和工作量的信息 默认每隔60分钟自动从SGA中获取一次 被易管理性监视器 MMOM 存在磁盘上 默认保存8天 可以在EM中单击 Server 服务器 选项卡 然后单击
  • 【数据库】Navicat远程连接oracle出现ORA 28547错误

    问题说明 用 Navicat Premium 15 连接oracle数据库 连接本地没有问题 远程连接oracle数据库时就出现问题 问题为 ORA 28547 connection to server failed probable Or
  • oracle数据库小结

    运用sqlplus连接数据库 sqlplus as sysdba 以系统用户 sqlplus username password 以普通用户登录 若忘记用户密码 则可以先以系统用户登录 然后运用alter user 用户名 identifi
  • Oracle expdp按条件导出

    今天我们来说说Oracle expdp按条件导出 expdp yt ed456 directory UWP DIR dumpfile NEW INDEX TOOL NOW dmp tables NEW INDEX TOOL NOW quer
  • 数据库 索引

    多数数据库 使用 B 树 Balance Tree 的结构来保存索引 B 树 最上层节点 根节点 最下层节点 叶子节点 两者之间的节点 中间节点 B 树 显著特征 从根节点 到各个叶子节点的距离都是相等的 如此 检索任何值时 都经过相同数目
  • oracle数据库下创建用户

    一 使用sqlplus 创建用户 1 登陆到sqlplus 2 键入 create user user name identified by password user name 要用户名 password 对应的密码 3 键入 Grant
  • Oracl之动态Sql编写总结

    一 概述 在通常的sql操作中 sql语句基本上都是固定的 如 SELECT t empno t ename FROM scott emp t WHERE t deptno 20 但有的时候 从应用的需要或程序的编写出发 都可能需要用到动态
  • oracle和mysql细微区别

    2 小的方面 语法等 mysql可以实现自增长主键 通过字段的auto increment属性 Oracle则需要通过序列 Sequence 来实现 mysql可以用双引号来引用字符串 当然单引号也行 Oracle只能用单引号 mysql在
  • 只要以查询数据的前三行如何处理

    select m name m numbs from select name count name as numbs from kh hbrc info t where t tpr fl 软件技术 and t xzzhw 软件部 group
  • Oracle数据库sql语句处理业务表重复数据取其一

    背景 在日常的工作中 我们会遇见一张表中存在重复的数据 这个重复的数据是指几个字段组成一个唯一索引的 但是因为在加工数据的过程中 会去掉这个唯一索引 但是在迁移到业务表中需要这个唯一索引 或者是业务要求等条件的 如下就演示了如何取其一 如下
  • ORACLE 序列sequence小结

    创建序列语法 需要获取相应的权限 create sequence NAME INCREMENT BY START WITH integer 初始值和递增间隔 MAXVALUE integer NOMAXVALUE 上界或无上界 MINVAL
  • Oracle数据泵、exp/imp工具导入导出数据

    一 最常用导出导入方案 exp imp命令工具 1 ssh工具连接服务器主机 exp命令导出 1 1将数据库全部数据导出 exp system password TestDB file bak dmp log exp log full y
  • Oracle 中换行chr(10)、回车chr(13)

    一 前言 chr n 返回 ascii 值对应的字符 ascii char 返回字符 char对应的ascii 值 chr n 和 ascii char 作用刚好是相反的 SQL gt select chr 65 from dual 控制台
  • Oracle的数据一致性机制原理

    一 前言 在单用户环境下 在操作数据库是不需要考虑其他用户会修改同一个数据 但是在多用户的情况下 多个事务可能会修改同一个数据 最终会得到错误的数据结果 Oracle数据库是通过 multiversion consistency model

随机推荐

  • 基础知识十一、Python解析网络报文之TCP首部报文解析

    文章目录 一 TCP首部解析器的实现 二 测试逻辑 上一节解析了 IP首部报文后 本节继续解析TCP报文首部 TCP协议处于OSI七层模型的传输层 传输层的作用就是负责管理端到端的通信连接问题 连续ARQ automatic repeat
  • 初始泛型类

    泛型的顶级理解 一 包装类 1 基本数据类型和对应的包装类 2 装箱和拆箱 3 自动装箱和拆箱 二 泛型 1 语法 2 泛型类的使用 3 示例 4 擦除机制 5 泛型上界 6 示例和复杂示例 7 泛型方法 一 包装类 在Java中 由于基本
  • JAVA 【爬虫】 Selenium 无头浏览,禁止加载图片,启动参数,失效,无效

    JAVA Selenium 无头浏览 禁止加载图片 启动参数 失效 无效 可能有如下几个原因 代码问题 命令参数写错 无头浏览 headless 禁止加载图片 blink settings imagesEnabled false Chrom
  • DS1302芯片介绍

    低功耗时钟芯片DS1302可以对年 月 日 时 分 秒进行计时 且具有闰年补偿等多种功能 DS1302的性能特性 实时时钟 可对秒 分 时 日 周 月以及带闰年补偿的年进行计数 用于高速数据暂存的31 8位RAM 最少引脚的串行I O 2
  • MySQL安装与使用(Windows)

    Windows平台提供了两种安装MySQL的方式 1 图形化安装 msi安装文件 链接 link 2 免安装 zip压缩文件 链接 link 安装MySQL 一 图形化安装 1 双击下载的 MySQL 安装文件 进入 MySQL 安装界面
  • Socket编程中的强制关闭与优雅关闭及相关socket选项

    以下描述主要是针对windows平台下的TCP socket而言 首先需要区分一下关闭socket和关闭TCP连接的区别 关闭TCP连接是指TCP协议层的东西 就是两个TCP端之间交换了一些协议包 FIN RST等 具体的交换过程可以看TC
  • 虚拟机三种网络模式

    基本知识 ipconfig查看信息 网关 Gateway 又称网间连接器 协议转换器 是你连接到的上层节点的地址 ip地址是你本身的地址 如果是路由器分配的 那么是路由器所构建的内网地址 网卡 需要网卡才能连接其他设备 是设备端的 交换机
  • vscode+phpstudy配置php环境

    1 先打开phpstudy 将WAMP启动 2 点击左侧的软件管理 随便选一个版本的php安装 我这里下的是5 3 29版本的 3 点击上面的系统环境 找到刚刚安装好的php 进入设置 点击扩展选项 将XDebug调试组件打开 并记下端口
  • MEF:COA-NET

    COA NET COLLABORATIVE ATTENTION NETWORK FOR DETAIL REFINEMENT MULTI EXPOSURE IMAGE FUSION COA NET 用于细节细化多曝光图像融合的协作关注网络 近
  • [Js进阶]如何用jquery获取到shadowRoot里的内容

    HTML组件相关的标准 HTML Template Shadow DOM 则是原生组件封装的基本工具 它可以实现组件与组件之间的独立性 Custom Elements 是用来包装原生组件的容器 通过它 你就只需要写一个标签 就能得到一个完整
  • python计算工资编程-Python实现扣除个人税后的工资计算器示例

    本文实例讲述了Python实现扣除个人税后的工资计算器 分享给大家供大家参考 具体如下 正好处于找工作期间避免不了会跟单位谈论薪资的情况 当然所有人跟你谈的都是税前收入 税后应该实际收入有多少呢 今天就简单写一个个人税收收入计算器 仅仅是觉
  • Linux下uboot编译出错(/bin/bash: arm-none-linux-gnueabi-gcc: command not found )

    unboot压缩包解压 tar xz 在终端进入解压目录 xz d tar xz tar xvf tar 向Makefile添加编译路径 在makefile的开头添加本机的编译路径 ARCH arm CROSS COMPILE opt fs
  • 【error】org.apache.catalina.core.StandardContext.startInternal 由于之前的错误,Context[/geoserver]启动失败

    error org apache catalina core StandardContext startInternal 由于之前的错误 Context geoserver 启动失败 tomcat10配置geoserver war包启动错误
  • Android 一些常见BUG汇总(持续更新)

    写在前面的话 每个开发者在工作中会遇到或多或少的小bug 这里博主把它们记录下来 以便以后查阅 开始 1 file storage emulated 0 DCIM xxx jpg exposed beyond app through Cli
  • [SDOI2012]拯救小云公主【bfs+二分答案】

    题目链接 正难则反 要直接求从起点到终点的最大距离 不妨反过来求最小的可以阻止骑士从起点到终点的对于全体圆的最小半径 那么 就是阻止从左上角到右下角的所有相交圆 于是 就是要变成没有从左上角到右下角的相交圆才可以 那么不妨跑一个bfs来判断
  • 全面分析冒泡排序过程

    冒泡排序也是一种简单直观的排序算法 其思想是 它重复地走访过要排序的数列 一次比较两个元素 如果他们的顺序错误就把他们交换过来 走访数列的工作是重复地进行直到没有再需要交换 也就是说该数列已经排序完成 这个算法的名字由来是因为越小的元素会经
  • leetcode分类刷题:二分查找(Binary Search)(二、隐藏有序序列的数学类型)

    参加了下2023届秋招 不得不感叹leetcode lintcode的题目实在太多了 也很难 特别对于我这种非科班生而言 感觉有必要分类整理一下 以便以后在工作中更好的应用 花了点时间刷了下二分查找的相关题目 刷的越多 反而越不会了 先把目
  • 还没做完的小程序

    include
  • 基于swiper使用vue-awesome-swiper 实现鼠标移入暂停自动播放、左右按钮控制前进后退、常见避坑、API中文文档地址

    vue 中使用swiper vue awesome swiper 鼠标移入暂停自动播放 左右按钮控制前进后退 常见避坑 swiper对应vue awesome swiper版本会带来很多坑点 推荐下面对照版本 帮大家避坑了 亲测可用 一 n
  • oracle 中的开窗函数over()

    开窗函数与聚合函数一样 都是对行的集合组进行聚合计算 它用于为行定义一个窗口 这里的窗口是指运算将要操作的行的集合 它对一组值进行操作 不需要使用GROUP BY子句对数据进行分组 能够在同一行中同时返回基础行的列和聚合列 反正我理解这个函