Over:窗口函数(滑动聚合)

本文涉及的产品
云数据库 RDS SQL Server,独享型 2核4GB
简介:

Over 窗口函数在Select 子句中,对查询的结果集进行“滑动-聚合”运算;如果使用count,那么基于滑动窗口的聚合语义同 base+1 累加;如果使用sum,那么基于滑动窗口的聚合语义等同于数据累加。Over()子句的运算顺序在Select 子句之后,在Order By子句之前。

滑动窗口计算原理:窗口的大小是由Over 的Partition By子句界定,窗口滑动的顺序是由Over的Order by子句指定。在计算聚合值时,使用<=(Order by Asc)或 >=(Order by Desc)计算滑动窗口的聚合值,某一个窗口的计算逻辑类似于

复制代码
select t.*, AggregationFuncation() Over(partition by t.ColumnName_Partition order by t.ColumnName_Order asc)
from dbo.TableName t

select AggregationFuncation
from dbo.TableName t
where t.ColumnName_Partition=Over_PartitionColumnValue
and t.ColumnName_Order<=Over_OrderColumnValue
复制代码

一,分区

1,创建示例数据

复制代码
--create table
create table dbo.dt_test
(
ID int,
Code int
)
go

--insert data
insert into dbo.dt_test(ID,Code)
values(3,1),(3,2),(1,1),(1,2),(2,3),(1,2)
go
复制代码

2,测试Over 创建函数的 滑动-聚合

--test over
select ID,Code, count(0) over(partition by Code order by ID) as Count_Over,
                sum(ID) over(partition by Code order by ID) as Sum_Over
from dbo.dt_test

查询的结果按照 Code 排序,在Over 函数中,按照Code分区,按照ID排序。

分析查询结果:

2.1,当Code=1时,在这个分区(窗口)中,有两行,ID分别是1,3

当Code=1,ID=1时,是分区的第一行,Count_Over=1,Sum_Over=1,这是滑动窗口的第一行,聚合值是的计算逻辑是

select count(0) as Count_Over,
    sum(ID) as Sum_Over
from dbo.dt_test
where Code=1 
and ID<=1

当Code=1,ID=3时,是分区的第二行,Count_Over=2,Sum_Over=4,这是滑动窗口的第二行,聚合值是的计算逻辑是

select count(0) as Count_Over,
    sum(ID) as Sum_Over from dbo.dt_test where Code=1 and ID<=3

2.2 当Code=2时,在这个分区中,有三种,ID分别是1,1,3

当Code=2,ID=1时,是分区的第一行,Count_Over=2,Sum_Over=2,这是滑动窗口的第一行,聚合值是的计算逻辑是

select count(0) as Count_Over,
    sum(ID) as Sum_Over from dbo.dt_test where Code=2 and ID<=1

当Code=2,ID=1时,是分区的第二行,Count_Over=2,Sum_Over=2,这是滑动窗口的第二行,聚合值是的计算逻辑是

select count(0) as Count_Over,
    sum(ID) as Sum_Over from dbo.dt_test where Code=2 and ID<=1

当Code=2,ID=3时,是分区的第三行,Count_Over=3,Sum_Over=5,这是滑动窗口的第三行,聚合值是的计算逻辑是

select count(0) as Count_Over,
    sum(ID) as Sum_Over from dbo.dt_test where Code=2 and ID<=3

3,Over 函数用于分组聚合函数

如果 Over 函数用于分区聚合函数,partition by子句是必需的,如果省略 Order by 子句,那么将对整个分区(窗口)进行聚合计算

select ID,Code, count(0) over(partition by Code) as Count_Over,
                sum(ID) over(partition by Code) as Sum_Over
from dbo.dt_test

查询的结果等价于(传统写法)

select ID,Code, (select count(0) from dbo.dt_test as ij where ij.Code=oj.Code) as Count_Over,
               (select sum(id) from dbo.dt_test as ij where ij.Code=oj.Code) as Sum_Over
from dbo.dt_test oj

相比传统写法,Over函数写法查询性能更好。

4,Over 函数用于排名函数

Over 函数用于排名函数时,Order by子句是必需的,如果省略partition by 子句,那么整个查询结果集是一个窗口,排名函数对整个窗口排名。

select ID,Code, row_number() over(order by Code) as RowID
from dbo.dt_test

如果使用partition by子句,那么排名函数在每一个分区中进行排名,每一行的排名是基于当前的分区。

select ID,Code, row_number() over(partition by code order by ID) as RowID
from dbo.dt_test

二,限制分区的数据行

在Over子句中,使用Rows 或Range 进一步限制分区的数据行,在使用时,必须注意:

  • 必需条件:Rows 和 Range必须跟在Order by 子句之后,对排序的结果进行限制;
  • Rows:使用固定的行数来限制分区中的数据行数量;The ROWS clause limits the rows within a partition by specifying a fixed number of rows preceding or following the current row.
  • Range:使用Value的范围来限制分区中的数据行数量,排序列的重复值,被认为是一个值;The RANGE clause logically limits the rows within a partition by specifying a range of values with respect to the value in the current row.
  • 在分区中,如果排序行不存在重复值,Rows和Range返回的结果是相同的;如果排序行存储在重复值,Rows和Range返回的结果可能不同;
  • Range子句只能从分区的开始或结尾到当前行开始计算,不能使用 <UINT_Number> PRECEDING 和<UINT_Number>  FOLLOWING;

使用在Rows 和 Range子句中的特殊关键字:

  • UNBOUNDED PRECEDING:指定分区的第一行
  • UNBOUNDED FOLLOWING:指定分区的最后一行
  • CURRENT ROW:指定分区的当前数据行
  • <UINT_Number> PRECEDING:在分区中,指定当前行之前的数据行数量,UINT_Number是>=0的整数
  • <UINT_Number> FOLLOWING:在分区中,指定当前行之后的数据行数量,UINT_Number是>=0的整数

1,对分区中的连续两行计算加和

计算逻辑是:在当前分区中,对当前行和其之后的1行数据计算加和;

select ID,Code,sum(code) over(partition by ID order by Code rows between current row and 1 following) as SumCode
from dbo.dt_test

2,对分区中的数据行,按照特定顺序,计算从第一行到当前行的累加值

计算逻辑是:从第一行到当前行,计算累加值

select ID,Code,
    sum(code) over(partition by ID order by Code rows unbounded preceding) as SumCode_Rows,
    sum(code) over(partition by ID order by Code range unbounded preceding) as SumCode_Range
from dbo.dt_test

 

参考文档:

OVER Clause (Transact-SQL)

SQL Server Window Function 窗体函数读书笔记二 - A Detailed Look at Window Functions

总结SQL Server窗口函数的简单使用

SQL Server中的窗口函数

作者悦光阴
本文版权归作者和博客园所有,欢迎转载,但未经作者同意,必须保留此段声明,且在文章页面醒目位置显示原文连接,否则保留追究法律责任的权利。
分类: SQL Server
标签: TSQL, Over







本文转自悦光阴博客园博客,原文链接:http://www.cnblogs.com/ljhdo/p/4533456.html,如需转载请自行联系原作者
相关实践学习
使用SQL语句管理索引
本次实验主要介绍如何在RDS-SQLServer数据库中,使用SQL语句管理索引。
SQL Server on Linux入门教程
SQL Server数据库一直只提供Windows下的版本。2016年微软宣布推出可运行在Linux系统下的SQL Server数据库,该版本目前还是早期预览版本。本课程主要介绍SQLServer On Linux的基本知识。 相关的阿里云产品:云数据库RDS&nbsp;SQL Server版 RDS SQL Server不仅拥有高可用架构和任意时间点的数据恢复功能,强力支撑各种企业应用,同时也包含了微软的License费用,减少额外支出。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/sqlserver
目录
相关文章
|
4月前
|
SQL 流计算
如果使用flinksql进行窗口关联操作,然后结合使用自定义表聚合函数,怎么对多表的window_start和window_end进行聚合操作?
如果使用flinksql进行窗口关联操作,然后结合使用自定义表聚合函数,怎么对多表的window_start和window_end进行聚合操作?
39 2
|
6月前
|
SQL 关系型数据库 API
Flink--9、双流联结(窗口联结、间隔联结)
Flink--9、双流联结(窗口联结、间隔联结)
|
SQL 存储 Linux
Hive 高阶--分组窗口函数--序列分组函数(CUME_DIST)|学习笔记
快速学习 Hive 高阶--分组窗口函数--序列分组函数(CUME_DIST)
248 0
|
SQL 移动开发 开发工具
Hive 高阶--分组窗口函数--取值分组函数( LAG,LEAD,FIRST_VALUE,LAST_VALUE)|学习笔记
快速学习 Hive 高阶--分组窗口函数--取值分组函数( LAG,LEAD,FIRST_VALUE,LAST_VALUE)
386 0
|
SQL 分布式计算 Java
聚合操作_groupBy_聚合操作 | 学习笔记
快速学习聚合操作_groupBy_聚合操作
98 0
聚合操作_groupBy_聚合操作 | 学习笔记
|
大数据 开发者
聚合操作_多维聚合_cube | 学习笔记
快速学习聚合操作_多维聚合_cube
59 0
聚合操作_多维聚合_cube | 学习笔记
|
SQL HIVE 开发者
Hive 高阶--分组窗口函数--聚合函数集成分组函数(SUM)|学习笔记
快速学习 Hive 高阶--分组窗口函数--聚合函数集成分组函数(SUM)
245 0
|
大数据 开发者
聚合操作_多维聚合_rollup | 学习笔记
快速学习聚合操作_多维聚合_rollup
71 0
聚合操作_多维聚合_rollup | 学习笔记
|
分布式计算 大数据 Spark
聚合操作_多维聚合_rollup 案例 | 学习笔记
快速学习聚合操作_多维聚合_rollup 案例
58 0
聚合操作_多维聚合_rollup 案例 | 学习笔记
|
SQL 存储 vr&ar
Hive 高阶--分组窗口函数--常见的分组函数(rank、denserank、rownumber、ntile)|学习笔记
快速学习 Hive 高阶--分组窗口函数--常见的分组函数(rank、denserank、rownumber、ntile)
286 0
Hive 高阶--分组窗口函数--常见的分组函数(rank、denserank、rownumber、ntile)|学习笔记

热门文章

最新文章