SQL函数 - 开窗(窗口)函数

这篇具有很好参考价值的文章主要介绍了SQL函数 - 开窗(窗口)函数。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

什么是开窗函数?

开窗函数对一组值进行操作,它不像普通聚合函数那样需要使用GROUP BY子句对数据进行分组,能够在同一行中同时返回基础行的列和聚合列

开窗函数的语法形式为:函数 + over(partition by <分组用列> order by <排序用列>),表示对数据集按照分组用列进行分区,并且并且对每个分区按照函数聚合计算,最终将计算结果按照排序用列排序后返回到该行。括号中的两个关键词partition by 和order by 可以只出现一个。

注意:开窗函数不会互相干扰,因此在同一个查询语句中可以同时使用多个开窗函数

开窗函数适用于 mysql 8.0以上版本, sql sever 、hive、oracle 等

开窗函数分类

窗口函数大致分为以下几类:

一、排序开窗函数

① row_number() -- 相同值排名顺延,返回结果1、2、3、4

② rank() -- 相同结果排名相同,后续排名不连续,返回结果为 1、2、2、4

③ dense_rank() -- 相同结果排名相同,后续排名顺延,返回结果为 1、2、2、3

④ ntile(n) -- 分组排名,将数据分为n组并返回对应组号1、2......n

具体例子如下:

select grades
,subjects
,results
,row_number() over(partition by grades,subjects order by results desc) as row_numbers
,rank() over(partition by grades,subjects order by results desc) as ranks
,dense_rank() over(partition by grades,subjects order by results desc) as dense_ranks
,ntile(3) over(partition by grades,subjects order by results desc) as ntiles
from test11

表示将数据集按照grades、subjects字段进行分组后,根据对应排序函数并按照results字段降序返回排名,具体结果如下

sql中开窗函数,数据湖,sql,大数据

二、聚合开窗函数

① sum() -- 分组求和

② count() -- 分组求总数

③ min() -- 分组求最小值

④ max() -- 分组求最大值

⑤ avg() --分组求均值

具体例子如下:

select grades
,subjects
,results
,sum(results) over(partition by grades,subjects order by results desc) as sum聚合1
,sum(results) over(partition by grades,subjects) as sum聚合2
,count(results) over(partition by grades,subjects order by results desc) as count聚合1
,count(results) over(partition by grades,subjects) as count聚合2
,min(results) over(partition by grades,subjects order by results desc) as min聚合1
,min(results) over(partition by grades,subjects) as min聚合2
,max(results) over(partition by grades,subjects order by results desc) as max聚合1
,max(results) over(partition by grades,subjects) as max聚合2
,avg(results) over(partition by grades,subjects order by results desc) as avg聚合1
,avg(results) over(partition by grades,subjects) as avg聚合2
from test11

聚合1表示将数据集按照grades、subjects进行分组后,按照results降序排序,将每组中的results依次聚合;

聚合2表示将数据集按照grades、subjects进行分组后,将每组中的results整体聚合。因此 count(results) over(partition by grades,subjects order by results desc) 与 row_number() over(partition by grades,subjects order by results desc) 可以达到同样目的

sql中开窗函数,数据湖,sql,大数据

深挖两者的差异,主要是 order by 默认统计范围是 rows between unbounded preceding and current row,也就是取当前行数据与当前行之前的数据运算。如果在聚合1 order by 条件的后面加上语句:rows between unbounded preceding and unbounded following,也就可以对分组中的所有数据进行运算,可以得到聚合1相同结果。如下

select grades
,subjects
,results
,sum(results) over(partition by grades,subjects order by results desc rows between unbounded preceding and unbounded following) as sum聚合1
,sum(results) over(partition by grades,subjects) as sum聚合2
,count(results) over(partition by grades,subjects order by results desc rows between unbounded preceding and unbounded following) as count聚合1
,count(results) over(partition by grades,subjects) as count聚合2
,min(results) over(partition by grades,subjects order by results desc rows between unbounded preceding and unbounded following) as min聚合1
,min(results) over(partition by grades,subjects) as min聚合2
,max(results) over(partition by grades,subjects order by results desc rows between unbounded preceding and unbounded following) as max聚合1
,max(results) over(partition by grades,subjects) as max聚合2
,avg(results) over(partition by grades,subjects order by results desc rows between unbounded preceding and unbounded following) as avg聚合1
,avg(results) over(partition by grades,subjects) as avg聚合2
from test11

sql中开窗函数,数据湖,sql,大数据

关于这一部分下文详细描述

三、其他开窗函数

① lag(字段名,n,0) -- 移位开窗函数,表示返回向上第n行指定字段对应数据。其中n代表向上偏移n行,0代表若偏移行数超出表范围则返回0也可以改成其他值,若不写则默认null

② lead(字段名,n,0) -- 移位开窗函数,与lag()相反,表示返回向下第n行指定字段对应数据

③ first_value() -- 取分组内排序后,截止到当前行,第一个值

④ last_value() -- 取分组内排序后,截止到当前行,最后一个值

具体例子如下:

#加order by
select grades
,subjects
,results
,lag(results,1,0) over(partition by grades,subjects order by results desc) as lag移位1
,lead(results,1,0) over(partition by grades,subjects order by results desc) as lead移位1
,first_value(results) over(partition by grades,subjects order by results desc) as first_value排序1
,last_value(results) over(partition by grades,subjects order by results desc) as last_value排序1
from test11

加 order by 代表将数据集按照grades、subjects进行分组后,再根据results降序排序,然后根据函数取当前行数据与当前行之前的数据运算。若不加 order by 则是对分组后的数据直接运算

sql中开窗函数,数据湖,sql,大数据

 #不加order by 
select grades
,subjects
,results
,lag(results,1,0) over(partition by grades,subjects) as lag移位2
,lead(results,1,0) over(partition by grades,subjects) as lead移位2
,first_value(results) over(partition by grades,subjects) as first_value排序2
,last_value(results) over(partition by grades,subjects) as last_value排序2
from test11

sql中开窗函数,数据湖,sql,大数据

不加 order by

⑤ ratio_to_report(字段名) over(partition by 字段名) -- 百分比分析函数,rratio_to_report(字段名) 为分子,over(partition by 字段名) 为分母,若分母中partition by 字段名 省略则表示占数据集整体百分比。为Oracle数据库函数,mysql不能使用

具体例子如下:

select grades
,subjects
,results
,ratio_to_report(results) over()  百分比函数1
,ratio_to_report(results) over(partition by grades,subjects) 百分比函数2
from test11

开窗函数的定位框架

窗口函数除了经常使用的 partition by <分组用列> order by <排序用列> 外,在order by 后存在可省略的窗口框架 range/rows between x and y ,主要用于对partition by的分组结果做进一步限制,并定位出限制后的运算范围。

其中range表示按照值的范围进行范围的定义,而rows表示按照行的范围进行范围的定义。若order by 后未指定框架,那么默认框架将采用 range unbounded preceding and current row,表示从开窗后的第一行到当前行。

若窗口函数没有order by,也就不存在框架range/rows between x and y。

框架range/rows between x and y 具体x、y可取值见下表:

可取值 含义
unbounded preceding partition by 分组order by后 第一行
unbounded following partition by 分组order by后 最后一行
current row partition by 分组order by后 当前行
n preceding partition by 分组order by后 前n行
n following partition by 分组order by后 后n行

说明:rows between 5 preceding and current row 可缩写为 rows 5 preceding

range 只支持使用 unbounded preceding、 unbounded following、current row

具体例子如下:

select grades
,subjects
,results
,sum(results) over(partition by grades,subjects order by results desc rows between unbounded preceding and current row) as 定位窗口求和1
,sum(results) over(partition by grades,subjects order by results desc range between unbounded preceding and current row) as 定位窗口求和2
from test11

sql中开窗函数,数据湖,sql,大数据

由结果可见,定位窗口求和1 中rows 按照固定行定义,此处表示返回从当前行到分组后第一行之和

定位窗口求和2 中range 按照值进行范围定义,此处仍表示返回从当前行到分组后第一行之和,不过由于当前行存在2个相同order by值(如上图黄框中89),则会先对这两行汇总后再向分组后第一行求和。

开窗函数使用场景

开窗函数应用比较多的场景,以下简单列举:

① 求某个分组下的最大/最小值/TOPn值对应信息,如年级中每个班级的第一名,大区中销售额最高城市,此处用排序函数row_number(),需用order by 排序

②对某个分组求和/个数/均值,如城市历史截至昨天累积销售额/营业天数/平均销售额,此处用sum()/count()/avg(),需用order by 默认的定位框架

③相邻时间求时间差,如用户复购时间周期,此处用lag(),需用order by 排序文章来源地址https://www.toymoban.com/news/detail-627384.html

到了这里,关于SQL函数 - 开窗(窗口)函数的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • SQL使用技巧(6)HIVE开窗函数

    开窗函数的使用铁律:不要滥用 先想明白自己要实现什么样的功能,然后再去实践。没有目的的尝试段不可取,会难以理解各开窗函数的真正用法。 如果没有现成可用HIVE库,可以参见本人 大数据单机学习环境搭建 系列文章。 1.1Hive建表 1.2数据准备 1.3保存为HDFS文件 1.4验证

    2024年02月08日
    浏览(46)
  • hive sql—开窗函数—累积求和和滑动求和

    数据集有三列数据,姓名、月份和数量: 图1 使用 sum() 函数和 over() 来实现,如下: 结果如下: 同一个name,后一个月份都是前几个月份的累加和 图2 需要稍微骚一点的操作,加上一个限制条件: 数字:可正可零可负,正往前,负向后;preceding:向前几行;following:向后几行

    2024年02月11日
    浏览(33)
  • 【大数据之Hive】十六、Hive-HQL函数之窗口函数(开窗函数)

      先定义了窗口的大小(按行来算),然后对窗口内的行的数据进行计算,再将计算结果返回给改行。   窗口函数包括窗口和函数两部分,窗口用于定义计算范围,函数用于定义计算逻辑,窗口函数只会在原来的表上增加一列结果列,不改变原来的数据。 函数:   绝

    2024年02月11日
    浏览(32)
  • 【SQL开发实战技巧】系列(二十七):数仓报表场景☞通过对移动范围进行聚集来详解分析函数开窗原理以及如何一个SQL打印九九乘法表

    【SQL开发实战技巧】系列(一):关于SQL不得不说的那些事 【SQL开发实战技巧】系列(二):简单单表查询 【SQL开发实战技巧】系列(三):SQL排序的那些事 【SQL开发实战技巧】系列(四):从执行计划讨论UNION ALL与空字符串UNION与OR的使用注意事项 【SQL开发实战技巧】系列

    2023年04月09日
    浏览(38)
  • spark sql 数据倾斜--join 同时开窗去重的问题优化

    背景: 需求:在一张查询日志表中,有百亿数据,需要join上维表,再根据几个字段进行去重 开窗去重和join 一定要分步进行 ,按照需求先做join再开窗,或者去重完成后在进行join。 dwd_tmp1 中存在百亿用户查询日志数据 数据倾斜 数据量超百亿,资源给到200 * 2c * 20G,执行引擎

    2024年02月11日
    浏览(38)
  • SQL—排序专用窗口函数

    下面介绍三种用于进行排序的专用窗口函数: 1、RANK()     在计算排序时,若存在相同位次,会跳过之后的位次。     例如,有3条排在第1位时,排序为:1,1,1,4······ 2、DENSE_RANK()     这就是题目中所用到的函数,在计算排序时,若存在相同位次,不会跳过之后的位

    2024年01月22日
    浏览(40)
  • SQL-窗口函数

    什么是窗口函数 可以像聚合函数一样对一组数据进行分析并返回结果,二者的不同之处在于,窗口函数不是将一组数据汇总成单个结果,而是为每一行数据都返回一个结果。 窗口函数组成部分 1.创建数据分区 窗口函数OVER子句中的PARTITION BY选项用于定义分区,其作用类似于查

    2024年01月19日
    浏览(29)
  • SQL助你面大厂(窗口函数)

           在面试过程中窗口函数的应用可谓是数不胜数,前提你要知道什么是窗口函数,最常用的窗口函数有哪些?语法是什么?分别用的场景是什么?今天会以这三个问题开始我们今天的学习 什么是窗口函数?        所谓的窗口函数就是动态处理数据的一类函数,也叫做

    2024年02月12日
    浏览(28)
  • SQL窗口分析函数使用详解系列三之偏移量类窗口函数

    本文以HiveSQL语法进行代码演示。 对于其他数据库来说同样也适用,比如SparkSQL,FlinkSQL以及Mysql8,Oracle,SqlServer等传统的关系型数据库。 已更新第一类聚合函数类,点击这里阅读 ①SQL窗口函数系列一之聚合函数类 ②SQL窗口函数系列二之分组排序窗口函数 本节介绍Hive窗口分

    2024年04月26日
    浏览(28)
  • 【sql高级】postgresql之窗口函数用法

    窗口函数在在SQL中是非常有用的工具,特别是在需要对查询结果进行分析、排名、聚合或者对结果进行一些特定的计算时。以下是一些常见的场景: 排名和分组:窗口函数可以轻松地对结果集进行排名、分组和分区。例如,你可以使用 ROW_NUMBER()、RANK()、DENSE_RANK() 等函数来为

    2024年03月23日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包