窗口函数 OVER(PARTITION BY ...)

  • 建表
  • OVER(PARTITION BY ... ORDER BY ... DESC)
  • 分组排序函数row_number()、rank() 、dense_rank()、ntile()的区别
  • 偏移分析窗口函数 lag()、lead()
  • 其他聚合函数

MySQL窗口函数,12.21.1 窗口功能说明 https://dev.mysql.com/doc/refman/8.0/en/window-function-descriptions.html

开窗函数的语法结构: 分析函数() over(partition by 分组列名 order by 排序列名 rows between 开始位置 and 结束位置)
over()函数 中包括三个函数:包括分区partition by 列名、排序order by 列名、指定窗口范围rows between 开始位置 and 结束位置
rows between … and … 用得较少,将在最后一节分析

我们知道聚合函数对一组值执行计算并返回单一的值,如sum(),count(),max(),min(), avg()等,这些函数常与group by子句连用。除了 COUNT 以外,聚合函数忽略空值。
       但有时候一组数据只返回一组值是不能满足需求的,如我们经常想知道各个地区的前几名、各个班或各个学科的前几名。这时候需要每一组返回多个值。用开窗函数解决这类问题非常方便。它和聚合函数的不同之处是:对于每个组返回多行,而聚合函数对于每个组只返回一行。

建表

DROP TABLE IF EXISTS tempCREATE TABLE temp(id INT,name VARCHAR(10),class VARCHAR(10),score INT
);INSERT INTO temp (id, name, class, score) VALUES (1,'公孙衍', '2', 81);
INSERT INTO temp (id, name, class, score) VALUES (2,'廉颇', '3', 55);
INSERT INTO temp (id, name, class, score) VALUES (3,'李牧', '3', 55);
INSERT INTO temp (id, name, class, score) VALUES (4,'王翦', '1', 96);
INSERT INTO temp (id, name, class, score) VALUES (5,'王贲', '1', 92);
INSERT INTO temp (id, name, class, score) VALUES (6,'白起', '1', 96);
INSERT INTO temp (id, name, class, score) VALUES (7,'蔺相如', '3', 90);
INSERT INTO temp (id, name, class, score) VALUES (8,'赵胜', '3', 81);
INSERT INTO temp (id, name, class, score) VALUES (9,'赵雍', '3', 93);
INSERT INTO temp (id, name, class, score) VALUES (10,'魏无忌', '2', 92);

OVER(PARTITION BY … ORDER BY … DESC)

无分组排序 分组排序(对班级)
SELECT name,class,score, ROW_NUMBER() OVER(ORDER BY score DESC) mm FROM temp SELECT name,class,score, ROW_NUMBER() OVER(PARTITION BY class ORDER BY score DESC) mm FROM temp
--这个也能实现无分组的排序,只是它没有排序后的次序(也就是没有上面的mm列)
SELECT  * FROM temp ORDER BY sroce DESC

实例:

查询每个班的第一名的成绩 查询每个班的最后一名的成绩
SELECT name,class,score FROM (SELECT name,class,score, RANK() OVER(PARTITION BY class ORDER BY score DESC) mm FROM TEMP ) a WHERE mm = 1; SELECT name,class,score FROM ( SELECT name,class,score, RANK() OVER(PARTITION BY class ORDER BY score) mm FROM temp ) a WHERE mm = 1;

在求第一名成绩的时候,不能用row_number(),因为如果同班有两个并列第一,mm=1就只返回一个结果
不加desc,排序就默认升序,取mm=1,就是最后一名

分组排序函数row_number()、rank() 、dense_rank()、ntile()的区别

  • select ROW_NUMBER()over(order by name) as 排序,* from temp
    — 排序,即使值一样,也不会重复排序。例如1,2,3,4,5
  • select RANK()over(order by name) as 排序,* from temp
    — 排序,值一样,就重复排序,有间隙。例如1,1,3,4
  • select DENSE_RANK()over(order by name) as 排序,* from temp
    — 排序,值一样,就重复排序,没有间隙。例如1,1,2,2,3,4,5
  • select NTILE(2)over(order by name) as 排序,* from temp
    — 排序,分成2组。此函数一般用于取表中前百分之几的数据。例如,取数据的前25%就将数据分4组,然后字段的条件是等于1。

SELECT *, 函数名 OVER(ORDER BY sroce DESC) AS 排序 FROM temp

ROW_NUMBER()      RANK()      DENSE_RANK()      NTILE(2)     

偏移分析窗口函数 lag()、lead()

lag和lead分析函数可以在同一次查询中,取出同一字段的 前N行的数据(lag)和 后N行的数据(lead)作为独立的列。
在实际应用中,若要用到取今天和昨天的某字段差值时,lag和lead函数的应用就显得尤为重要。当然,这种操作可以用表的自连接实现,但是lag和lead与left join、right join 等自连接相比,效率更高,SQL更简洁。

lag(exp_str, offset, defval) over(partition by … order by …)
lead(exp_str, offset, defval) over(partition by … order by …)

  • exp_str 是字段名称
  • offset 是偏移量, 即是上1个或上N个的值,假设当前行在表中排在第5行,则offset 为3,则表示我们所要找的数据行就是表中的第2行(即5-3=2) 。offset默认值为1。
  • defval 默认值, 当两个函数取上N/下N个值,当在表中从当前行位置向前数N行已经超出了表的范围时,lag()函数将defval这个参数值作为函数的返回值,若没有指定默认值,则返回NUL,那么在数学运算中,总要给一个默认值才不会出错。

lag() 实例

SELECT id,score,
LAG(score,1,0)OVER() AS n1,
LAG(score,1)  OVER() AS n2,
LAG(score,2,0)OVER() AS n6,
LAG(score,2)  OVER() AS n7
FROM temp

lead() 实例

SELECT id,score,
LEAD(score,1,0)OVER() AS n1,
LEAD(score,1)  OVER() AS n2,
LEAD(score,2,0)OVER() AS n6,
LEAD(score,2)  OVER() AS n7
FROM temp

其他聚合函数

名称 描述
CUME_DIST() 累计分配值
DENSE_RANK() 当前行在其分区内的排名,没有间隙
FIRST_VALUE() 窗口框架第一行的参数值
LAG() 来自分区内滞后当前行的行的参数值
LAST_VALUE() 窗口框架最后一行的参数值
LEAD() 分区内行前导当前行的参数值
NTH_VALUE() 来自第 N 行窗口框架的参数值
NTILE() 其分区内当前行的桶数
PERCENT_RANK() 百分比排名值
RANK() 当前行在其分区内的排名,有间隙
ROW_NUMBER() 其分区内的当前行数

group by是对检索结果的保留行进行单纯分组,一般和聚合函数一起使用例如max、min、sum、avg、count等一块用。 partition by虽然也具有分组功能,但同时也具有其他的高级功能。

sum() over()的使用
显示全部字段是为了方便查看,当有明确目标的时候可以适当选择相应字段。

SELECT t.*, SUM(t.score) s_sum FROM temp t GROUP BY t.class SELECT t.*, SUM(t.score) OVER(PARTITION BY t.class ORDER BY t.score DESC) s_sum FROM TEMP t SELECT t.*, SUM(t.score) OVER(ORDER BY t.id) s_sum FROM temp t

avg() over()的使用
计算移动平均值,一般用于股票变化。
n个数值{x1,x2,x3,...,xn}\{ {x_1,x_2,x_3,...,x_n}\}{x1​,x2​,x3​,...,xn​},按顺序取一定个数所做的全部算术平均值。例如 x1+x2+x33,x2+x3+x43,x3+x4+x53,x4+x5+x63,.....\frac{x_1+x_2+x_3}{3},\frac{x_2+x_3+x_4}{3},\frac{x_3+x_4+x_5}{3},\frac{x_4+x_5+x_6}{3},.....3x1​+x2​+x3​​,3x2​+x3​+x4​​,3x3​+x4​+x5​​,3x4​+x5​+x6​​,..... 等就是移动平均值。

SELECT id, score, AVG(score) OVER(ORDER BY id ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) FROM temp

ROWS BETWEEN 2 PRECEDING AND CURRENT ROW
限制计算移动平均值的范围,本语句包含本行和前两行。

语法总结:
avg(…A…) over(partition by …b… order by …C… rows between …D1… and …D2…)
sum(…A…) over(partition by …b… order by …C… rows between …D1… and …D2…)

  • A:需要被加工的字段名称
  • B:分组的字段名称
  • C:排序的字段名称
  • D:计算的行数范围

窗口范围说明:

  • preceding:往前
  • following:往后
  • current row:当前行
  • unbounded:起点(一般结合preceding,following使用)
  • unbounded preceding表示该窗口最前面的行(起点)
  • unbounded following:表示该窗口最后面的行(终点)

比如:

  • rows between unbounded preceding and current row - - 表示本行和之前所有的行
  • rows between current row and unbounded following - - 表示本行和之后所有的行
  • rows between 3 preceding and current row - - 表示往前3行到本行(共计4行)
  • rows between 3 preceding and 1 following - - 表示往前3行到往后1行(共计5行)

下面还有很多用法,就不逐一列举了,简单介绍一下,和上面用法类似:
count() over(partition by … order by …):求分组后的总数。
max() over(partition by … order by …):求分组后的最大值。
min() over(partition by … order by …):求分组后的最小值。
avg() over(partition by … order by …):求分组后的平均值。
lag() over(partition by … order by …):取出前n行数据。  
lead() over(partition by … order by …):取出后n行数据。
first_value() over(partition by … order by …):取出第一个数据。
last_value() over(partition by … order by …):取出最后一个数据。
ratio_to_report() over(partition by … order by …):Ratio_to_report() 括号中就是分子,over() 括号中就是分母。
percent_rank() over(partition by … order by …)

窗口函数 OVER(PARTITION BY ...)相关推荐

  1. LeetCode MySQL 585. 2016年的投资(窗口函数over(partition by xx))

    文章目录 1. 题目 2. 解题 1. 题目 写一个查询语句,将 2016 年 (TIV_2016) 所有成功投资的金额加起来,保留 2 位小数. 对于一个投保人,他在 2016 年成功投资的条件是: ...

  2. Hive窗口函数(over/partition by/order by/window/序列函数)总结与实践

    一.简介 本文主要介绍Hive中的窗口函数,Hive中的窗口函数和SQL中的窗口函数相类似,都是用来做一些数据分析类的工作,一般用于olap分析(在线分析处理). 二.概念 我们都知道在sql中有一类 ...

  3. 窗口函数(防忘笔记)

    本文参考自知乎帖子:https://zhuanlan.zhihu.com/p/92654574 面试热门预警. 实话说在接触窗口函数前,我对SQL的了解无外乎就是select, from, where ...

  4. 数据窗口retrieve查询结果生成新表_SQL系列之窗口函数及经典使用场景,如topN排名问题...

    日常生活中,经常会遇到需要在每组内排名的问题,比如每个部门按业绩排名,找出每个部门排名前N的员工等,面对这类需求,就需要使用SQL的高级功能--窗口函数. 窗口函数,也叫联机分析处理函数(Online ...

  5. SQL实战篇:SQL窗口函数及真题

    在数据分析师面试笔试过程中,窗口函数是各大公司笔试题中高频出现的知识点,因为在实际工作中,很多涉及到组内排名或求topN等相关的问题,都有一个共同的特点,实现起来不是简单的表连接或者聚合函数就可以完成 ...

  6. SQL进阶,子查询与窗口函数

    本节给大家讲解SQL在实际过程中用途比较多的子查询与窗口函数,下面一起学习. 示例工具:MySQL8.0.Navicat Premium 12 本文讲解内容:子查询与窗口函数 适用范围:SQL进阶应用 ...

  7. SQL数据分析实战:好用的窗口函数

    今天给大家分享下关于SQL的窗口函数基础. 目录: 1. 窗口函数是什么 2. 排序函数 3. 分布函数 4. 前后函数 5. 首尾函数 6. 聚合函数 1. 窗口函数是什么 窗口函数,也叫OLAP函 ...

  8. select函数_SQL高级功能:窗口函数

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

  9. plsql打开sql窗口快捷键_SQL干货|为你打开一扇窗—窗口函数

    前言 很早之前就想写一篇关于窗口函数的文章,因精力有限所以一直搁置了(一脸认真的自我检讨),在这篇文章的准备阶段,我也拜读了一些相关文章,总体来说基本上所涉及的窗口函数相关知识均有涉及,但一万个读者有 ...

  10. sql累计求和时间太长_(七)SQL知识点--窗口函数

    目录 1.窗口函数 1.1定义 窗口函数,即OLAP函数(Online Anallytical Prcessing,联机分析处理),可以对数据库数据进行实时分析处理.具备分组.排序,同时又不减少原表行 ...

最新文章

  1. 最新最全GPT-3模型网络结构详细解析
  2. 不怕面试再问 Activity,一次彻底地梳理(原理+生命周期)
  3. 怎么样Windows7在配置ASPserverIIS
  4. CSS选择器详解(一)常用选择器
  5. php实现隐藏字符串的功能
  6. python matplotlib画图遇到的问题——标题重叠问题
  7. 这座中国小城,靠“造假”称霸一个全球市场
  8. 鼠标指向表格时 显示更多信息 toolTipController1
  9. 希望你婚后的每一天我都能过得快乐。。。
  10. 乌班图服务器系统升级,快速从Ubuntu 20.10升级到Ubuntu 21.04的方法
  11. SR 学习记录----JUNOS为例
  12. 中国开发者将迎来黄金十年
  13. 个人看过的动漫、动画电影推荐
  14. Jetson嵌入式系列模型部署-3
  15. 研究生招生信息网服务器异常,2012研究生网上报名常见问题汇总
  16. 可视化界面:Activity 详解
  17. win10打不开gpedit.msc的解决方法
  18. 6月12gta5服务器维护,gta520176月11日这会更新什么了 | 手游网游页游攻略大全
  19. ug后处理如何加密_UG编程中如何添加后处理文件呢?小小干货拿走不谢
  20. 抖音上农民伯伯出的题,真的会难倒清华北大的高材生吗?

热门文章

  1. Linux 之十五 Kernel 仓库、Kernel 协作方式、订阅邮件列表、提交 PATCH
  2. 05.前端面经汇总javaScript篇
  3. [随笔] flex 布局使用 space-between 尾行排版效果优化
  4. 在Java中为JFrame添加背景音乐
  5. win10打不开计算机配置似乎是正确的,Win10系统软件打不开提示“并行配置不正确”如何解决...
  6. css中margin和padding设置成百分比时参照物是谁
  7. 信息安全技术——(十五)物联网关键技术
  8. 阿里云2核4G云服务器租用CPU内存、公网带宽和系统盘配置
  9. windows 7家庭版升级为旗舰版 序列
  10. 使用udp 发送一张jpeg图片,upd接收后转成opencv的Mat格式