让人抓耳挠腮-窗口函数

注:以下代码在MYSQL中运行完成

最近学习了窗口函数,统一书写形式为:

函数名(某字段)over(partition by 分区字段 order by 排序字段)

一共有两个括号,括号里面可以填参数,也可以不填,依据函数的不同而决定。下面将介绍7种窗口函数。使用价值体现在,无视select后字段的限制,自己玩自己。

一、汇总函数

1. 函数内容:

5种

函数特点

1.sum(字段) over (partition by 分区的字段 order by 排序的字段 desc/asc)

第一行到当前行字段累计汇总值
如果相同的值则对应的累计汇总值相同

2.avg(字段) over (partition by 分区的字段 order by 排序的字段 desc/asc)

第一行到当前行字段累计平均值
如果相同的值则对应的累计平均值相同

3.count(字段) over (partition by 分区的字段 order by 排序的字段 desc/asc)

第一行到当前行的累计计数
如果相同的值则对应的累计计数相同

4.Max(字段) over (partition by 分区的字段 order by 排序的字段 desc/asc)

第一行到当前行的最大值
往往配合滑动函数使用

5.min(字段) over (partition by 分区的字段 order by 排序的字段 desc/asc)

第一行到当前行的最小值
往往配合滑动函数使用

2.运算逻辑:

第一行到当前行

3.运算举例

下面以sum()over()函数举例子

新建一个表test1

create table test1(organization varchar(20), ranking int, number_ int);

insert into test1 values(1,1,1),(1,1,2),(2,1,2),(3,1,3),(1,2,5), (1,3,4),(2,3,6),(2,3,6),(3,3,5),(1,2,3), (2,2,5),(3,4,4),(2,2,5),(3,2,3);

test1表中的数据

其中比较搞不清楚的是over后面两个参数的作用,通过实验,得出以下结论

函数

结果

特性

1.sum(字段)over()

按照表整体,对字段进行汇总,表中每一行都填入最终汇总值

汇总

2.sum(字段)over(partition by 分区的字段)

在分区字段内,对字段进行汇总,分区内的每一行都填入对应分区汇总的数值

汇总

3.sum(字段)over(order by 排序的字段 desc/asc)

按照表整体,按照排序字段进行累计,排序字段如果出现相同值,则累计数值相同

累加

4.sum(字段)over(partition by 分区的字段 order by 排序的字段 desc/asc)

在分区字段内,按照排序字段进行累计,排序字段如果出现相同值,则累计数值相同

累加

下面用实际的例子来演示一下

1.sum(字段)over()

可以看到sum(number_) over()这一列,汇总了number_这一列,表中每一行都填入最终汇总值。

2.sum(字段)over(partition by 分区的字段)

可以看到sum(number_) over(partition by organization)这一列,按照organization这一列将数据分区,并按照分区汇总了number_这一列,表中每一行都填入最终汇总值。

3.sum(字段)over(order by 排序的字段 desc/asc)

添加图片注释,不超过 140 字(可选)

4.sum(字段)over(partition by 分区的字段 order by 排序的字段 desc/asc)

可以看到sum(number_) over(partition by organization order by ranking)这一列,按照organization这一列将数据分区,并按照ranking这一列排序,再去累计number_这一列,结果是每一行的值是第一行到当前行的累加值,如果按照排序的ranking字段有相同值,则累计数值相同。比如上图第1行与第2行,ranking的值都是1,最终值3,是二者累加值,并且最后一列第1行与第2行值相同。同理第3行与第4行;第7行与第8行;第9行与第10行。

总结:

不加order by,无论添加partition by与否,都是计算的汇总值,不是累计值。

二、排序函数

1.函数内容:

3种

函数特点

row_number()over(partition by 分区的字段 order by 排序的字段 desc/asc)

排名连续

rank()over(partition by 分区的字段 order by 排序的字段 desc/asc)

排名不连续,值相同时采用并列排名

dense_rank()over(partition by 分区的字段 order by 排序的字段 desc/asc)

排名连续,值相同时采用并列排名

2.运算逻辑:

第一行到最后一行

3.运算举例

新建表st_score

create table st_score(st_id int,name varchar(100),gender varchar(100),score int,lesson varchar(100)); insert into st_score values(20200001,'小明','男',85,'Math'), (20200001,'小明','男',90,'Chinese'), (20200001,'小明','男',89,'English'), (20200002,'小宁','男',92,'Math'), (20200002,'小宁','男',81,'Chinese'), (20200002,'小宁','男',83,'English'), (20200008,'杰伦','男',88,'Math'), (20200008,'杰伦','男',88,'Chinese'), (20200008,'杰伦','男',88,'English'), (20200009,'小娜','女',83,'Math'), (20200009,'小娜','女',87,'Chinese'), (20200009,'小娜','女',78,'English'), (20200009,'小娜','女',82,'Math'), (20200009,'小娜','男',85,'dama'), (20200008,'杰伦','男',87,'Math');

现在按照每个学生来进行三科成绩的排名,看一下每个学生,分别是哪一门成绩最好,使用排序函数

SELECT * ,row_number()over(PARTITION by name order by score desc) as rn_rownum ,rank()over(PARTITION by name order by score desc) as rn_rank ,dense_rank()over(PARTITION by name order by score desc) as rn_dense FROM st_score ss ;

结果如下:

从结果可以看出,当成绩没有相同值时,三种排序函数的结果一致,比如:小娜,小宁,小明。但是当成绩出现重复值时,结果发生了变化,比如:杰伦同学有三个88的成绩,在row_number中,无视重复值,按照顺序直接排列下来;rank和dense_rank是重复值都按照相同的排名排序,但是rank的排序是断裂的,1,1,1,4,dense_rank排名是连续的1,1,1,2。

三、分布函数

四、前后函数

1.函数内容

2种

函数特点

lead(字段,N ) over (partition by 分区的字段 order by 排序的字段 desc/asc)

向前,求当前行的前第N行数据

lag(字段,N ) over (partition by 分区的字段 order by 排序的字段 desc/asc)

向后,求当前行的后第N行数据

2.运算逻辑

第一行到最后一行

3.运算逻辑

以lag函数举例子,lead函数逻辑同理。

原始数据

(1)lag(字段 ,N) over ( )

over()内没有指定分区字段和排序字段,按照全部数据,原始排序。结果求的是每一行数据的dimDateID字段的后一行数据。

(2)lag(字段 ,N) over (partition by分区字段)

over()内指定会员号dimMemberID分区内,排序不变。结果求的是不同会员号内,每一行数据的dimDateID字段的后一行数据,可以发现,与没有指定partition by分区字段相比,指定分区后,会员号32、35后一行数据,为null值。

(3)lag(字段 ,N) over (order by 排序字段)

全部数据排序

over()内全部数据,排序按照dimDateID字段生序。结果求的是每一行数据的dimDateID字段的后一行数据。

(4)lag(字段 ,N) over (partition by分区字段 order by 排序字段 asc/desc)

分区内排序

默认生序排列asc

降序排列desc

over()内指定会员号dimMemberID分区内,按照dimDateID在分区内排序。结果求的是不同会员号内,按照指定字段排序后,每一行数据的dimDateID字段的后一行数据。

五、头尾函数

1.函数内容

2.运算逻辑

3.运算逻辑

六、ntile

1.函数内容

2.运算逻辑

3.运算逻辑

七、nthnth_value

1.函数内容

2.运算逻辑

3.运算逻辑

  • 25
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
您遇到的错误消息 "'nvm' 不是内部或外部命令,也不是可运行的程序或批处理文件" 是由于您的计算机上没有安装 Node Version Manager(NVM)或者没有正确配置。NVM 是一个用于管理和切换 Node.js 版本的工具。要解决此问题,您可以按照以下步骤进行操作: 1. 首先,确保您已经安装了 NVM。您可以从 NVM 的官方网站(https://github.com/nvm-sh/nvm)上找到适合您操作系统的安装说明,并按照指南进行安装。 2. 安装完成后,重新启动您的终端窗口或命令提示符,并再次尝试运行 'nvm' 命令。 3. 如果问题仍然存在,请检查是否正确配置了 NVM。您可以通过在终端中运行以下命令来检查: ``` nvm --version ``` 如果显示了 NVM 的版本号,则表明已正确配置。否则,您需要添加 NVM 的路径到系统环境变量中。 对于 Windows 用户,您可以按照以下步骤添加环境变量: - 右键点击“我的电脑”(或“此电脑”),选择“属性”。 - 在左侧面板中,点击“高级系统设置”。 - 在弹出的窗口中,点击“环境变量”按钮。 - 在“系统变量”部分中,找到名为“Path”的变量,并双击打开它。 - 点击“新建”按钮,并输入 NVM 的安装路径(例如:C:\Users\YourUsername\AppData\Roaming\nvm)。 - 确认所有对话框并保存更改,然后重新启动终端窗口或命令提示符。 对于 macOS 和 Linux 用户,您可以编辑 `~/.bashrc` 或 `~/.bash_profile` 文件,并添加以下行: ``` export NVM_DIR="$HOME/.nvm" [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm ``` 保存更改后,重新启动终端窗口或命令提示符。 希望这些步骤能够帮助您解决问题。如果问题仍然存在,请提供更多详细信息,以便我们进一步帮助您解决。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值