返回顶部
首页 > 资讯 > 数据库 >一篇文章看懂SQL中的开窗函数
  • 422
分享到

一篇文章看懂SQL中的开窗函数

2024-04-02 19:04:59 422人浏览 独家记忆
摘要

目录OVER的定义OVER的语法OVER的用法OVER在聚合函数中使用的示例SUM后的开窗函数COUNT后的开窗函数OVER在排序函数中使用的示例ROW_NUMBER()RANK() DENSE_RANK()&

OVER的定义

OVER用于为行定义一个窗口,它对一组值进行操作,不需要使用GROUP BY子句对数据进行分组,能够在同一行中同时返回基础行的列和聚合列。

OVER的语法

OVER ( [ PARTITioN BY column ] [ ORDER BY culumn ] )

PARTITION BY 子句进行分组;

ORDER BY 子句进行排序。

窗口函数OVER()指定一组行,开窗函数计算从窗口函数输出的结果集中各行的值。

开窗函数不需要使用GROUP BY就可以对数据进行分组,还可以同时返回基础行的列和聚合列。

OVER的用法

OVER开窗函数必须与聚合函数或排序函数一起使用,聚合函数一般指SUM(),MAX(),MIN,COUNT(),AVG()等常见函数。排序函数一般指RANK(),ROW_NUMBER(),DENSE_RANK(),NTILE()等。

OVER在聚合函数中使用的示例

我们以SUM和COUNT函数作为示例来给大家演示。

--建立测试表和测试数据
CREATE TABLE Employee
(
ID INT  PRIMARY KEY,
Name VARCHAR(20),
GroupName VARCHAR(20),
Salary INT
)
INSERT INTO  Employee
VALUES(1,'小明','开发部',8000),
      (4,'小张','开发部',7600),
      (5,'小白','开发部',7000),
      (8,'小王','财务部',5000),
      (9, null,'财务部',NULL),
      (15,'小刘','财务部',6000),
      (16,'小高','行政部',4500),
      (18,'小王','行政部',4000),
      (23,'小李','行政部',4500),
      (29,'小吴','行政部',4700);

SUM后的开窗函数

SELECT *,
     SUM(Salary) OVER(PARTITION BY Groupname) 每个组的总工资,
     SUM(Salary) OVER(PARTITION BY groupname ORDER BY ID) 每个组的累计总工资,
     SUM(Salary) OVER(ORDER BY ID) 累计工资,
     SUM(Salary) OVER() 总工资
from Employee

(提示:可以左右滑动代码)

结果如下:

一篇文章看懂SQL中的开窗函数

其中开窗函数的每个含义不同,我们来具体解读一下:

SUM(Salary) OVER (PARTITION BY Groupname)

只对PARTITION BY后面的列Groupname进行分组,分组后求解Salary的和。

SUM(Salary) OVER (PARTITION BY Groupname ORDER BY ID)

对PARTITION BY后面的列Groupname进行分组,然后按ORDER BY 后的ID进行排序,然后在组内对Salary进行累加处理。

SUM(Salary) OVER (ORDER BY ID)

只对ORDER BY 后的ID内容进行排序,对排完序后的Salary进行累加处理。

SUM(Salary) OVER ()

对Salary进行汇总处理

COUNT后的开窗函数

SELECT *,
       COUNT(*) OVER(PARTITION BY Groupname ) 每个组的个数,
       COUNT(*) OVER(PARTITION BY Groupname ORDER BY ID) 每个组的累积个数,
       COUNT(*) OVER(ORDER BY ID) 累积个数 ,
       COUNT(*) OVER() 总个数
from Employee

返回的结果如下图:

一篇文章看懂SQL中的开窗函数

后面的每个开窗函数就不再一一解读了,可以对照上面SUM后的开窗函数进行一一对照。

OVER在排序函数中使用的示例

我们对4个排序函数一一演示

--先建立测试表和测试数据
WITH t AS
(SELECT 1 StuID,'一班' ClassName,70 Score
UNION ALL
SELECT 2,'一班',85
UNION ALL
SELECT 3,'一班',85
UNION ALL
SELECT 4,'二班',80
UNION ALL
SELECT 5,'二班',74
UNION ALL
SELECT 6,'二班',80
)
SELECT * INTO Scores FROM t;
SELECT * FROM Scores

ROW_NUMBER()

定义:ROW_NUMBER()函数作用就是将SELECT查询到的数据进行排序,每一条数据加一个序号,他不能用做于学生成绩的排名,一般多用于分页查询,比如查询前10个 查询10-100个学生。ROW_NUMBER()必须与ORDER BY一起使用,否则会报错。 

对学生成绩排序

SELECT *,
ROW_NUMBER() OVER (PARTITION BY ClassName ORDER BY SCORE DESC) 班内排序,
ROW_NUMBER() OVER (ORDER BY SCORE DESC) AS 总排序
FROM Scores;

结果如下:

一篇文章看懂SQL中的开窗函数

这里的PARTITION BY和ORDER BY的作用与我们在上面看到的聚合函数的作用一样,都是用来进行分组和排序使用的。

此外ROW_NUMBER()函数还可以取指定顺序的数据。

SELECT * FROM (
SELECT *, ROW_NUMBER() OVER (ORDER BY SCORE DESC) AS 总排序
FROM Scores
) t WHERE t.总排序=2;

结果如下:

一篇文章看懂SQL中的开窗函数

RANK() 

定义:RANK()函数,顾名思义排名函数,可以对某一个字段进行排名,这里和ROW_NUMBER()有什么不一样呢?ROW_NUMBER()是排序,当存在相同成绩的学生时,ROW_NUMBER()会依次进行排序,他们序号不相同,而Rank()则不一样。如果出现相同的,他们的排名是一样的。下面看例子:

示例

SELECT ROW_NUMBER() OVER (ORDER BY SCORE DESC) AS [RANK],*
FROM Scores;
 
SELECT RANK() OVER (ORDER BY SCORE DESC) AS [RANK],*
FROM Scores;

结果:

一篇文章看懂SQL中的开窗函数

一篇文章看懂SQL中的开窗函数

其中上图是ROW_NUMBER()的结果,下图是RANK()的结果。当出现两个学生成绩相同是里面出现变化。RANK()是1-1-3-3-5-6,而ROW_NUMBER()则还是1-2-3-4-5-6,这就是RANK()和ROW_NUMBER()的区别了。

DENSE_RANK() 

定义:DENSE_RANK()函数也是排名函数,和RANK()功能相似,也是对字段进行排名,那它和RANK()到底有什么不同那?特别是对于有成绩相同的情况,DENSE_RANK()排名是连续的,RANK()是跳跃的排名,一般情况下用的排名函数就是RANK() 我们看例子:

示例

SELECT 
RANK() OVER (ORDER BY SCORE DESC) AS [RANK],*
FROM Scores;
 
SELECT 
DENSE_RANK() OVER (ORDER BY SCORE DESC) AS [RANK],*
FROM Scores;

结果如下:

一篇文章看懂SQL中的开窗函数

一篇文章看懂SQL中的开窗函数

上面是RANK()的结果,下面是DENSE_RANK()的结果

NTILE()

定义:NTILE()函数是将有序分区中的行分发到指定数目的组中,各个组有编号,编号从1开始,就像我们说的'分区'一样 ,分为几个区,一个区会有多少个。  

SELECT *,NTILE(1) OVER (ORDER BY SCORE DESC) AS 分区后排序 FROM Scores;
SELECT *,NTILE(2) OVER (ORDER BY SCORE DESC) AS 分区后排序 FROM Scores;
SELECT *,NTILE(3) OVER (ORDER BY SCORE DESC) AS 分区后排序 FROM Scores;

结果如下:

一篇文章看懂SQL中的开窗函数

一篇文章看懂SQL中的开窗函数

一篇文章看懂SQL中的开窗函数

就是将查询出来的记录根据NTILE函数里的参数进行平分分区。

总结

OVER开窗函数是我们工作中经常要使用到的,特别是在做数据分析计算的时候,经常要对数据进行分组排序。上面我们额外介绍了聚合函数和排序函数的与OVER结合的使用方法,此外还有很多与OVER一起使用的函数,比如LEAD函数,LAG函数,STRING_AGG函数等等都会使用到开窗函数OVER,其使用方法也要务必掌握。

到此这篇关于sql中开窗函数的文章就介绍到这了,更多相关SQL开窗函数内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

您可能感兴趣的文档:

--结束END--

本文标题: 一篇文章看懂SQL中的开窗函数

本文链接: https://lsjlt.com/news/33932.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 一篇文章看懂SQL中的开窗函数
    目录OVER的定义OVER的语法OVER的用法OVER在聚合函数中使用的示例SUM后的开窗函数COUNT后的开窗函数OVER在排序函数中使用的示例ROW_NUMBER()RANK() DENSE_RANK()&...
    99+
    2024-04-02
  • 一篇文章弄懂Python中的内建函数
    目录前言A类B类C类D类E类F类G类H类I类L类M类R类S类T类总结前言 python内建函数指的是python自带的函数,这种函数不需要定义,并且不同的内建函数具有不同的功能,可以...
    99+
    2024-04-02
  • 一篇文章看懂Vue组合式API
    目录一. 为什么要使用Composition API1.1.一个Options API实例1.2.Options API存在的问题1.3.Composition API简介二.Com...
    99+
    2023-05-14
    vue 组合式api的意义 vue3组合式api教程 vue2使用组合式api
  • 一篇文章让你看懂封装Axios
    目录前言拦截器不要返回数据,依然返回 AxiosResponse 对象不推荐的做法推荐的做法为你的请求添加拓展支持请求重试支持 jsonp 请求支持 URI 版本控制保持请求唯一后语...
    99+
    2024-04-02
  • 一篇文章看懂Java异常处理
    目录异常的定义异常的分类异常的处理方法try…catch处理throw 和throws自定义异常总结异常的定义 在java中,异常就是java在编译、运行或运行过程中出现的错误 总共...
    99+
    2024-04-02
  • 一篇文章看懂Java字符串操作
    目录✨字符, 字节与字符串字符与字符串字节与字符串✨字符串常见操作字符串比较字符串查找 字符串替换 字符串拆分 字符串截取其他操作方法总结✨字符, 字节与字符串 字符与字符串 字符串...
    99+
    2024-04-02
  • 一篇文章读懂Golang init函数执行顺序
    目录1.init 函数简介2.执行顺序2.1 单个源文件的 init 执行顺序2.2 单个包的 init 执行顺序2.3 main 包导入多个包时 init 执行顺序2.3.1 不存...
    99+
    2024-04-02
  • Python一篇文章看懂时间日期对象
    目录一、时间对象time1.测量运行时间方法①process_time()②perf_counter()③monotonic()2.函数性能计算器二、日期对象datetime1.格式...
    99+
    2024-04-02
  • 一篇文章弄懂C#中的async和await
    目录前言 async await 从以往知识推导 创建异步任务 创建异步任务并返回Task 异步改同步 说说 await Task 说说 async Task<TResult&...
    99+
    2024-04-02
  • 一篇文章弄懂ECMAScript中的操作符
    目录一元操作符 布尔操作符 乘性操作符 加性操作符 关系操作符 相等操作符 条件操作符 赋值操作符 逗号操作符 总结一元操作符 只能操作一个值的操作符叫做一元操作符 递增和递减。递...
    99+
    2024-04-02
  • 一篇文章搞懂Go语言中的Context
    目录0 前置知识sync.WaitGroup1 简介2 context.Context引入3 context包的其他常用函数3.1 context.Background和contex...
    99+
    2024-04-02
  • 一篇文章弄懂Mybatis中#和$的区别
    目录前言一:下面我们写个关于“#”的个sql,看能不能注入。1.正常传参2.拼接传参二:下面我们写个关于“$”的个sql,看能不能注入。1.正常传参2.拼接传参总结前言 在学校的时候...
    99+
    2024-04-02
  • 一篇文章弄懂js中的typeof用法
    目录基础返回类型string 和 booleannumber 和 bigintsymbolundefinedfunctionobject其他常见问题引用错误typeof nullty...
    99+
    2024-04-02
  • Java读取excel的方式,一篇文章看懂(详细)
    目录 一、excel读取的两种方式 1.1 jxl 和 poi 的区别和选择 二、jxl 的使用 2.1 导入相关依赖  2.2 操作 三、poi 的使用 3.1 导入相关依赖 3.2 操作 四、总结 一、excel读取的两种方式 J...
    99+
    2023-09-03
    java jar intellij-idea spring
  • 一篇文章彻底弄懂C++虚函数的实现机制
    目录1、虚函数简介2、虚函数表简介3、有继承关系的虚函数表剖析3.1、单继承无虚函数覆盖的情况3.2、单继承有虚函数覆盖的情况3.3、多重继承的情况3.4、多层继承的情况4、总结1、...
    99+
    2024-04-02
  • Python 一篇文章看懂Python集合与字典数据类型
    目录前言一、集合类型1.定义2.集合使用方式3.集合推导式4.可变集合二、字典类型1.定义2.字典的使用方式3.字典推导式4.代码练习总结前言 集合数据类型是没有顺序的简单对象的聚集...
    99+
    2024-04-02
  • SQL中的开窗函数(窗口函数)
    目录窗口函数1.1 排序窗口函数rank1.2 rank(), dense_rank(), row_number()区别1.3 排序截取数据lag(),lead(),ntile(),cume_dist()1.4 聚合函数...
    99+
    2024-04-02
  • 一篇文章弄懂Java8中的时间处理
    目录前言LocalDateTimeZonedDateTimeInstant总结前言 java8借鉴了第三方日期库joda很多的优点 java.time包 类名描述Instant时间戳...
    99+
    2024-04-02
  • 一篇文章读懂nginx的gzip_static模块
    Nginx支持静态和动态两种包体gzip压缩方式,分别对应模块ngx_http_gzip_static,ngx_http_gzip。 我们知道gzip是CPU密集型的应用,实时动态压...
    99+
    2024-04-02
  • 一篇文章读懂nginx的gzip功能
    目录前言语义:拓扑:仿真:验证:gzip_proxied的参数解析:小结:总结前言 HTTP中包体【body】压缩协商对应的头字段为Accept-Encoding/Content-E...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作