TSql Over 窗口函数(滑动聚合)
2015-12-14 13:50
239 查看
Over 窗口函数,能够在Select 子句中,对查询的结果集进行“滑动-聚合”运算;如果使用count,那么基于滑动窗口的聚合语义同 base+1 累加;如果使用sum,那么基于滑动窗口的聚合语义等同于数据累加。
Over()子句的运算顺序在Select 子句之后,在Order By子句之前。
滑动窗口计算原理:窗口的大小是由Over 的Partition By子句界定,窗口滑动的顺序是由Over的Order by子句指定。在计算聚合值时,使用<=(Order by Asc)或 >=(Order by Desc)计算滑动窗口的聚合值,某一个窗口的计算逻辑类似于
1,创建示例数据
2,测试Over 创建函数的 滑动-聚合
查询的结果按照 Code 排序,在Over 函数中,按照Code分区,按照ID排序。
分析查询结果:
2.1当Code=1时,在这个分区(窗口)中,有两行,ID分别是1,3
当Code=1,ID=1时,是分区的第一行,Count_Over=1,Sum_Over=1,这是滑动窗口的第一行,聚合值是的计算逻辑是
当Code=1,ID=3时,是分区的第二行,Count_Over=2,Sum_Over=4,这是滑动窗口的第二行,聚合值是的计算逻辑是
2.2当Code=2时,在这个分区中,有三种,ID分别是1,1,3
当Code=2,ID=1时,是分区的第一行,Count_Over=2,Sum_Over=2,这是滑动窗口的第一行,聚合值是的计算逻辑是
当Code=2,ID=1时,是分区的第二行,Count_Over=2,Sum_Over=2,这是滑动窗口的第二行,聚合值是的计算逻辑是
当Code=2,ID=3时,是分区的第三行,Count_Over=3,Sum_Over=5,这是滑动窗口的第三行,聚合值是的计算逻辑是
3,Over 函数用于分组聚合函数
如果 Over 函数用于分区聚合函数,partition by子句是必需的,如果省略 Order by 子句,那么将对整个分区(窗口)进行聚合计算
查询的结果等价于(传统写法)
相比传统写法,Over函数写法查询性能更好。
4,Over 函数用于排名函数
Over 函数用于排名函数时,Order by子句是必需的,如果省略partition by 子句,那么整个查询结果集是一个窗口,排名函数对整个窗口排名。
如果使用partition by子句,那么排名函数在每一个分区中进行排名,每一行的排名是基于当前的分区。
参考文档:
http://www.cnblogs.com/biwork/p/3244527.html https://msdn.microsoft.com/zh-cn/library/ms189461.aspx http://www.cnblogs.com/jeffwongishandsome/archive/2010/12/04/1896672.html http://www.cnblogs.com/CareySon/p/3411176.html
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
参考文档:
http://www.cnblogs.com/biwork/p/3244527.html https://msdn.microsoft.com/zh-cn/library/ms189461.aspx http://www.cnblogs.com/jeffwongishandsome/archive/2010/12/04/1896672.html http://www.cnblogs.com/CareySon/p/3411176.html
相关文章推荐
- oracle 创建 用户 表空前 授权示例
- oracle 创建 用户 表空前 授权示例
- Oracle递归查询
- keepalived +mysql 实战
- Oracle中的Union、Union All、Intersect、Minus
- mssqlserver SQL注释快捷键
- MySQL数据库性能优化之缓存参数优化
- oracle添加日志表
- Spark入门实战系列--6.SparkSQL(下)--Spark实战应用
- Spark入门实战系列--6.SparkSQL(中)--深入了解SparkSQL运行计划及调优
- 我用到的常用SQL
- c#windowform连接数据库的两种方法
- Oracle函数介绍:decode
- 在数据库查询时遇到死循环查询问题
- sqlite 如果确定任何地方都没有问题,但是运行时还有问题,那么查看表里有没有逗号
- mysql启动错误1067:进程意外终止
- SQLServer-----使用jTDS连接SQLServer数据库
- Spark入门实战系列--6.SparkSQL(上)--SparkSQL简介
- oracle导出Clob字段的方法
- SQL中Union和UnionAll的使用