点击关注上方“SQL数据库开发”,

设为“置顶或星标”,第一时间送达干货

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

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

结果如下:

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

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

返回的结果如下图:

后面的每个开窗函数就不再一一解读了,可以对照上面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;

结果如下:

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

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

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

结果如下:

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;

结果:

其中上图是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;

结果如下:

上面是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;

结果如下:

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

总结

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


我是岳哥,最后给大家分享我写的SQL两件套:《SQL基础知识第二版》和《SQL高级知识第二版》的PDF电子版。里面有各个语法的解释、大量的实例讲解和批注等等,非常通俗易懂,方便大家跟着一起来实操。有需要的读者可以下载学习,在下面的公众号「数据前线」(非本号)后台回复关键字:SQL,就行数据前线
——End——后台回复关键字:1024,获取一份精心整理的技术干货
后台回复关键字:进群,带你进入高手如云的交流群。
推荐阅读
再见,杀毒软件之父,王江民!又一个程序员,被抓捕!我的电脑不联网,很安全,黑客:你还有风扇呢。。。CentOS 已死,“免费”的RHEL没了一套简单实用的SQL脚本,总有你需要的

SQL窗口函数OVER详细用法,一学就会相关推荐

  1. select函数fdwrite用法_通俗易懂的学会:SQL窗口函数

    ​一.窗口函数有什么用? 在日常工作中,经常会遇到需要在每组内排名,比如下面的业务需求: 排名问题:每个部门按业绩来排名 topN问题:找出每个部门排名前N的员工进行奖励 面对这类需求,就需要使用sq ...

  2. 三种开窗函数详细用法,图文详解

    开窗函数的详细用法 一,开窗函数的语法 二,从聚合开窗函数sum(score) over(partition by name )讲起 三,开窗函数之first_value,last_value,lea ...

  3. MySQL - SQL窗口函数

    1.应用场景 窗口函数解决的问题包括: 1)排名问题 2)top N问题 应用工作中, 面试中. 2.学习/操作 前言 MySQL版本8已支持窗口函数这个功能, 如果低于该版本, 会出现SQL报错! ...

  4. Oracle SQL Loader的详细语法

    Oracle   SQL   Loader的详细语法 SQL*LOADER是ORACLE的数据加载工具,通常用来将操作系统文件迁移到ORACLE数据库中.SQL*LOADER是大型数据 仓库选择使用的 ...

  5. mysql left/right join算法效率分析_mysql left join,right join,inner join超详细用法分析

    MySQL left join,right join,inner join超详细用法分析 下面是例子分析 表A记录如下: aID        aNum 1           a20050111 2 ...

  6. Oracle SQL Loader的详细语法

    转载 http://www.cnblogs.com/binking/archive/2006/11/21/567587.html Oracle   SQL   Loader的详细语法   SQL*LO ...

  7. Hive SQL 窗口函数

    本文首发:大数据每日哔哔-Hive SQL 窗口函数 Hive 的窗口函数 在 SQL 中有一类函数叫做聚合函数,例如 sum().avg().max().min() 等等,这类函数可以将多行数据按照 ...

  8. oracle rtrim(),Oracle ltrim() rtrim() 函数详细用法

    嘿嘿,今天在论坛里看了一篇帖子,讨论ltrim() 函数的详细用法,下面我借几个高手的回答总结一下: 先看几个实例: SQL> select ltrim('109224323','109') f ...

  9. python 窗口函数_太好用了!Python中8种流行的SQL窗口函数了解一下!

    有关如何在业务分析中利用Pandas来有效复制最常用的SQL窗口函数的教程. 任何致力于构建公司KPI或创建分析随着时间推移的业务绩效的数据分析人员都知道SQL窗口功能是一个强大的工具.使用它们的真正 ...

最新文章

  1. 如何删除mac通用二进制文件
  2. windows 2012 exchange server 2013 搭建
  3. 循序渐进 OSPF的详细剖析(三)
  4. PMCAFF微课堂 (已结束)| 京东平台产品负责人:如何打造一个支撑3200万日订单量的平台型产品
  5. Android 无法查看外部依赖jar的源码的问题
  6. java中三种常见内存溢出错误的处理方法(good)
  7. IOS中,在两个ViewController之间传值
  8. 2012Android开发热门资料110
  9. 开源编译工具和编译软件
  10. Nacos服务注册发现
  11. 微课有关计算机应用基础,【计算机仿真论文】微课在计算机应用基础课的应用(共3802字)...
  12. django.db.utils.DataError: (1366, “Incorrect string value: ‘\\xE5\\x85\\xAD\\xE5\\x8D\\x83‘ for colu
  13. CodeForces 576C Points on Plane 莫队
  14. Python分析捕食者和被捕食者模型 Lotka--Volterra方程 | 拟合求解a,b,c,d
  15. 【转】PM、RD、QA、OP英文缩写
  16. vim设定utf8编码格式
  17. MD5文件加密和解密
  18. [贴图]TVB香港大部分演员照片、姓名(值得收藏)
  19. 课程设计 齿轮油泵泵体的机械加工工艺规程及工艺夹具装备设计
  20. 随机生成10个0-100的正整数

热门文章

  1. 盏茶python(五) 函数
  2. 生成器 Generator
  3. mysql -%3e卡在_华为nova3e为什么卡
  4. 爬虫selenium-java
  5. node.js中req和res对象的作用
  6. 多协程抓取薄荷网食物热量 下篇
  7. NAND FLASH学习笔记之MTD下nand flash驱动(三)
  8. 【VMware虚拟机】VMware虚拟机中网络连接类型对比【转载】
  9. 学习Java的第十天
  10. 为「IT女神勋章」而战