广告
返回顶部
首页 > 资讯 > 数据库 >SQL中的开窗函数(窗口函数)
  • 743
分享到

SQL中的开窗函数(窗口函数)

2024-04-02 19:04:59 743人浏览 泡泡鱼
摘要

目录窗口函数1.1 排序窗口函数rank1.2 rank(), dense_rank(), row_number()区别1.3 排序截取数据lag(),lead(),ntile(),cume_dist()1.4 聚合函数

窗口函数

  • 简单理解,就是对查询的结果多出一列,这一列可以是聚合值,也可以是排序值。
  • 开窗函数一般就是说的是over()函数,其窗口是由一个 OVER 子句 定义的多行记录
  • 开窗函数一般分为两类,聚合开窗函数和排序开窗函数。

简单来说,窗口函数有以下功能:

1)同时具有分组和排序的功能

2)不减少原表的行数

3)语法如下:

<窗口函数> over (partition by <用于分组的列名>
        order by <用于排序的列名> [rows between ?? and ???])

<窗口函数>的位置,可以放以下两种函数:

1) 专用窗口函数,包括后面要讲到的rank, dense_rank, row_number等专用窗口函数。

2) 聚合函数,如sum(). avg(), count(), max(), min()等,rows between…and…

因为窗口函数是对where或者group by子句处理后的结果进行操作,所以窗口函数原则上只能写在select子句中。

3)业务需求“在每组内排名”,比如:

  • 排名问题:每个部门按业绩来排名
  • topN问题:找出每个部门排名前N的员工进行奖励

1.1 排序窗口函数rank

-- 如果我们想在每个班级内按成绩排名,得到下面的结果。
select *,
 rank() over (partition by 班级
        order by 成绩 desc) as ranking
from 班级表;

我们来解释下这个sql语句里的select子句。rank是排序的函数。要求是“每个班级内按成绩排名”,这句话可以分为两部分:

1)每个班级内:按班级分组

  • partition by用来对表分组。在这个例子中,所以我们指定了按“班级”分组(partition by 班级)

2)按成绩排名

  • order by子句的功能是对分组后的结果进行排序,默认是按照升序(asc)排列。在本例中(order by 成绩 desc)是按成绩这一列排序,加了desc关键词表示降序排列。

通过下图,我们就可以理解partiition by(分组)和order by(在组内排序)的作用了。 

img

group by分组汇总后改变了表的行数,一行只有一个类别。而partiition by和rank函数不会减少原表中的行数。

preview

注意事项

  • partition子句可是省略,省略就是不指定分组,只是按成绩由高到低进行了排序。但是,这就失去了窗口函数的功能,所以一般不要这么使用。
  • 窗口函数原则上只能写在select子句中

1.2 rank(), dense_rank(), row_number()区别

select *,
   rank() over (order by 成绩 desc) as ranking,
   dense_rank() over (order by 成绩 desc) as dese_rank,
   row_number() over (order by 成绩 desc) as row_num
from 班级表

得到结果:

img

从上面的结果可以看出:

  • rank函数:这个例子中是5位,5位,5位,8位,也就是如果有并列名次的行,会占用下一名次的位置。比如正常排名是1,2,3,4,但是现在前3名是并列的名次,结果是:1,1,1,4。
  • dense_rank函数:这个例子中是5位,5位,5位,6位,也就是如果有并列名次的行,不占用下一名次的位置。比如正常排名是1,2,3,4,但是现在前3名是并列的名次,结果是:1,1,1,2。
  • row_number函数:这个例子中是5位,6位,7位,8位,也就是不考虑并列名次的情况。比如前3名是并列的名次,排名是正常的1,2,3,4。

1.3 排序截取数据lag(),lead(),ntile(),cume_dist()

  • LAG(col,n,default_val):获取往前第n行数据,col是列名,n是往上的行数,当第n行为null的时候取default_val
  • LEAD(col,n, default_val):往后第n行数据,col是列名,n是往下的行数,当第n行为null的时候取default_val
  • NTILE(n):把有序分区中的行分发到指定数据的组中,各个组有编号,编号从1开始,对于每一行,NTILE返回此行所属的组的编号。
  • cume_dist(),计算某个窗口或分区中某个值的累积分布。假定升序排序,则使用以下公式确定累积分布:

小于等于当前值x的行数 / 窗口或partition分区内的总行数。其中,x 等于 order by 子句中指定的列的当前行中的值。

1.4 聚合函数作为窗口函数

聚和窗口函数和上面提到的专用窗口函数用法完全相同,只需要把聚合函数写在窗口函数的位置即可,但是函数后面括号里面不能为空,需要指定聚合的列名。

我们来看一下窗口函数是聚合函数时,会出来什么结果:

select *,
   sum(成绩) over (order by 学号) as current_sum,
   avg(成绩) over (order by 学号) as current_avg,
   count(成绩) over (order by 学号) as current_count,
   max(成绩) over (order by 学号) as current_max,
   min(成绩) over (order by 学号) as current_min
from 班级表

img

如上图,聚合函数sum在窗口函数中,是对自身记录、及位于自身记录以上的数据进行求和的结果。比如0004号,在使用sum窗口函数后的结果,是对0001,0002,0003,0004号的成绩求和,若是0005号,则结果是0001号~0005号成绩的求和,以此类推。

不仅是sum求和,平均、计数、最大最小值,也是同理,都是针对自身记录、以及自身记录之上的所有数据进行计算,

这样使用窗口函数有什么用呢?

聚合函数作为窗口函数,可以在每一行的数据里直观的看到,截止到本行数据,统计数据是多少(最大值、最小值等)。同时可以看出每一行数据,对整体统计数据的影响。

1.5 over(- - rows between and )

sum()/... over ([partition by 列名] [order by 列名] [rows between ... and ...] )
-- 从起点到当前行数据聚合
between unbounded preceding and current row
-- 往前2行到往后1行的数据聚合
between 2 preceding and 1 following

rows必须跟在Order by 子句之后,对排序的结果进行限制,使用固定的行数来限制分区中的数据行数量。

  • OVER():指定分析函数工作的数据窗口大小,这个数据窗口大小可能会随着行的变而变化。
  • CURRENT ROW:当前行
  • n PRECEDING:往前n行数据
  • n FOLLOWING:往后n行数据
  • UNBOUNDED:起点,unbounded preceding 表示从表数据的起点, unbounded following表示到后面的终点
select name,subject,score,
sum(score) over() as sum1,
sum(score) over(partition by subject) as sum2,
sum(score) over(partition by subject order by score) as sum3,
-- 由起点到当前行的窗口聚合,和sum3一样
sum(score) over(partition by subject order by score rows between unbounded preceding and current row) as sum4,
-- 当前行和前面一行的窗口聚合
sum(score) over(partition by subject order by score rows between 1 preceding and current row) as sum5,
-- 当前行的前面一行和后面一行的窗口聚合
sum(score) over(partition by subject order by score rows between 1 preceding AND 1 following) as sum6,
-- 当前和后面所有的行
sum(score) over(partition by subject order by score rows between current row and unbounded following) as sum7
from t_fraction;
+-------+----------+--------+-------+-------+-------+-------+-------+-------+-------+
| name | subject | score | sum1 | sum2 | sum3 | sum4 | sum5 | sum6 | sum7 |
+-------+----------+--------+-------+-------+-------+-------+-------+-------+-------+
| 孙悟空  | 数学    | 12   | 359  | 185  | 12  | 12  | 12  | 31  | 185  |
| 沙悟净  | 数学    | 19   | 359  | 185  | 31  | 31  | 31  | 104  | 173  |
| 猪八戒  | 数学    | 73   | 359  | 185  | 104  | 104  | 92  | 173  | 154  |
| 唐玄奘  | 数学    | 81   | 359  | 185  | 185  | 185  | 154  | 154  | 81  |
| 猪八戒  | 英语    | 11   | 359  | 80  | 11  | 11  | 11  | 26  | 80  |
| 孙悟空  | 英语    | 15   | 359  | 80  | 26  | 26  | 26  | 49  | 69  |
| 唐玄奘  | 英语    | 23   | 359  | 80  | 49  | 49  | 38  | 69  | 54  |
| 沙悟净  | 英语    | 31   | 359  | 80  | 80  | 80  | 54  | 54  | 31  |
| 孙悟空  | 语文    | 10   | 359  | 94  | 10  | 10  | 10  | 31  | 94  |
| 唐玄奘  | 语文    | 21   | 359  | 94  | 31  | 31  | 31  | 53  | 84  |
| 沙悟净  | 语文    | 22   | 359  | 94  | 53  | 53  | 43  | 84  | 63  |
| 猪八戒  | 语文    | 41   | 359  | 94  | 94  | 94  | 63  | 63  | 41  |
+-------+----------+--------+-------+-------+-------+-------+-------+-------+-------+

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

您可能感兴趣的文档:

--结束END--

本文标题: SQL中的开窗函数(窗口函数)

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

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

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • SQL中的开窗函数(窗口函数)
    目录窗口函数1.1 排序窗口函数rank1.2 rank(), dense_rank(), row_number()区别1.3 排序截取数据lag(),lead(),ntile(),cume_dist()1.4 聚合函数...
    99+
    2022-08-25
  • SQL窗口函数之排名窗口函数的使用
    目录案例分析案例使用的示例表1.环比分析2.同比分析3.复合增长率4.不同产品最高和最低销售额示例表和脚本关于窗口函数的基础,请看文章SQL窗口函数 取值窗口函数可以用于返回窗口内指...
    99+
    2022-11-13
  • SQL窗口函数之取值窗口函数的使用
    目录案例分析1.环比分析2.同比分析3.复合增长率4.不同产品最高和最低销售额示例表和脚本关于窗口函数的基础,请看文章SQL窗口函数 取值窗口函数可以用于返回窗口内指定位置的数据行。...
    99+
    2022-11-13
  • SQL窗口函数之排名窗口函数怎么使用
    这篇文章主要介绍“SQL窗口函数之排名窗口函数怎么使用”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“SQL窗口函数之排名窗口函数怎么使用”文章能帮助大家解决问题。取...
    99+
    2022-10-19
  • SQL 窗口函数简介
    目录一、什么是窗口函数二、窗口函数的语法2.1 能够作为窗口函数使用的函数三、语法的基本使用方法——使用 RANK 函数四、无需指定 PARTITION BY五、专用窗口函数的种类六、窗口函数的适用范围七、作为窗口函数使用的聚合函数八、计...
    99+
    2014-09-29
    SQL 窗口函数简介
  • SQL窗口函数之聚合窗口函数的使用(count,max,min,sum)
    目录案例分析1.移动平均值2.累计求和(ROW)3.累计求和(RANGE)示例表和脚本关于窗口函数的基础,请看文章SQL窗口函数 许多常见的聚合函数也可以作为窗口函数使用,包括AVG...
    99+
    2022-11-13
  • 什么是SQL窗口函数
    本篇内容主要讲解“什么是SQL窗口函数”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“什么是SQL窗口函数”吧!窗口函数(Window Function) 是 SQL2003 标准中定义的一项新特...
    99+
    2023-06-15
  • SQL窗口函数是什么
    这篇文章主要介绍了SQL窗口函数是什么,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。窗口函数形如:表达式 OVER (PARTITION BY 分组字段 ORDER BY 排...
    99+
    2023-06-29
  • 与SQL窗口函数相同
    窗口函数的目的是以声明的方式将业务报告需求转换为SQL,从而使查询性能和开发人员/业务分析师的效率得到显着提高。 我看到现实世界的报告和仪表板在使用窗口功能后从几小时到几分钟,几分钟到几秒钟。 ...
    99+
    2022-10-18
  • SQL中的开窗函数是什么
    本篇内容主要讲解“SQL中的开窗函数是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“SQL中的开窗函数是什么”吧!OVER的定义OVER用于为行定义一个窗口...
    99+
    2022-10-19
  • SQL窗口函数怎么使用
    本文小编为大家详细介绍“SQL窗口函数怎么使用”,内容详细,步骤清晰,细节处理妥当,希望这篇“SQL窗口函数怎么使用”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。什么是窗口函数S...
    99+
    2022-10-19
  • Mysql 窗口函数
    一, MySQl 8.0 窗口函数 窗口函数适用场景: 对分组统计结果中的每一条记录进行计算的场景下, 使用窗口函数更好, 注意, 是每一条!! 因为MySQL的普通聚合函数的结果(如 group...
    99+
    2023-09-17
    scala spark java
  • Hive-窗口函数
    在Hive中支持窗口函数,Mysql在8.0版本后也支持使用,用好之后犹如开挂! Window Function又称为窗口函数、分析函数。聚合函数可以将多行数据按照规定聚合为一行,一般来讲聚集后的行数要少于聚集前的行数。但是有时我...
    99+
    2018-02-08
    Hive-窗口函数
  • SQL窗口函数的使用方法
    目录什么是窗口函数窗口函数组成部分1.创建数据分区2.分区内的排序3.指定窗口大小窗口函数分类1.聚合窗口函数2.排名窗口函数3.取值窗口函数什么是窗口函数 SQL窗口函数为在线分析...
    99+
    2022-11-13
  • MYSQL窗口函数(Rows & Range)——滑动窗口函数用法
    语法介绍 窗口函数语法: over (partition by order by rows/range子句 ) 可以放以下两种函数: 1) 专用窗口函数,包括后面要讲到的rank, den...
    99+
    2023-09-03
    mysql 数据库
  • MySQL 开窗函数
    目录(1)开窗函数的定义(2)开窗函数的实际应用场景结合order by关键词和limit关键词是可以解决很多的topN问题,比如从二手房数据集中查询出某个地区的最贵的10套房,从电...
    99+
    2022-11-13
  • MySQL:开窗函数
    当查询条件需要用到复杂子查询时,聚合函数操作起来非常麻烦,因此使用开窗函数能够轻松实现。 注意:在Oracle中称为分析函数。            在MySQL中称为开窗函数,使用于MySQL8.0以上版本,sql sever、hive、...
    99+
    2023-09-03
    mysql 数据库
  • SQL中常用的窗口函数(排序函数)-row_number/rank/dense_rank/ntile
    总结四个函数的特点: row_number():连续不重复;1234567 rank() :重复不连续;1222567 dense_rank():重复且连续;1222345 ntile():平均分组;...
    99+
    2023-09-05
    mysql 数据库 大数据
  • oracle的开窗函数
    原创select *  from (select province,               ...
    99+
    2022-10-18
  • sql 窗口函数ROW_NUMBER() 分组/排序/计数
    ROW_NUMBER() 窗口函数 / 分析函数 MySQL中,row_number() 函数 用来分区的,使用它 为返回的结果集中的每一行 生成一个序列号(为行分配序号),第一个数字以1开头。 主要用来计数的,也便于用此函数针对全部字段进...
    99+
    2023-08-20
    sql 数据库 mysql
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作