限制窗口函数

时间:2016-11-28 21:01:06

标签: sql sql-server sql-server-2012

我们假设我们有一个包含3个字段的表,customer_id,month,usage。

对于任何给定月份,我希望查看前几个月和当前月份的当前使用情况,总使用量和平均使用情况。

现在我可以为整个数据集执行此操作。但是让我说我​​想这样做一个月。

DROP TABLE #TEST2
create table #test2 (cx_id int, month int, usage int)

insert into #test2 values
(123,1,10),(123,2,11),(123,3,5),(123,4,19),(222,2,4),(222,3,19),(222,4,20),(123,5,1),(222,5,NULL),(123,6,0),(222,6,10)

select cx_id, t1.month, usage, 
sum(cast(isnull(usage,0) as numeric(5,2))) over (partition by cx_id order by t1.month rows between unbounded preceding and 1 preceding) as prev_sum,
avg(cast(isnull(usage,0) as numeric(5,2))) over (partition by cx_id order by t1.month rows between unbounded preceding and 1 preceding) as prev_avg,
sum(cast(isnull(usage,0) as numeric(5,2))) over (partition by cx_id order by t1.month rows between 1 following and unbounded following) as next_sum,
avg(cast(isnull(usage,0) as numeric(5,2))) over (partition by cx_id order by t1.month rows between 1 following and unbounded following) as next_avg
from #test2 t1
order by cx_id, month

在上面的代码中添加where month = 4会导致prev和next字段的NULL值,因为限制会在窗口函数运行之前启动。

显而易见的解决方案是对整个数据集运行查询,保存结果,然后使用select * where month = 4查询结果。但我的目标是避免处理整个数据集。

谢谢

编辑:

封装建议似乎有效:

select * from (
select cx_id, month, usage, 
sum(cast(isnull(usage,0) as numeric(5,2))) over (partition by cx_id order by t1.month rows between unbounded preceding and 1 preceding) as prev_sum,
avg(cast(isnull(usage,0) as numeric(5,2))) over (partition by cx_id order by t1.month rows between unbounded preceding and 1 preceding) as prev_avg,
sum(cast(isnull(usage,0) as numeric(5,2))) over (partition by cx_id order by t1.month rows between 1 following and unbounded following) as next_sum,
avg(cast(isnull(usage,0) as numeric(5,2))) over (partition by cx_id order by t1.month rows between 1 following and unbounded following) as next_avg
from #test2 t1 ) t where t.month =4

给出这个:

  

客户端执行时间16:40:02查询配置文件统计信息编号   INSERT,DELETE和UPDATE语句0 0.0000受影响的行数   INSERT,DELETE或UPDATE语句0 0.0000 SELECT数   语句2 2.0000 SELECT语句返回的行3 3.0000
  交易次数0 0.0000网络统计数量   服务器往返3 3.0000从客户端3发送的TDS数据包3.0000
  从服务器18收到的TDS数据包18.0000字节发送自   client 1538 1538.0000从服务器63629 63629.0000收到的字节   时间统计客户端处理时间16 16.0000总计   执行时间62 62.0000服务器上的等待时间回复46 46.0000

虽然

select cx_id, month, usage,  sum(cast(isnull(usage,0) as numeric(5,2))) over (partition by cx_id order by t1.month rows between unbounded preceding and 1 preceding) as prev_sum, avg(cast(isnull(usage,0) as numeric(5,2))) over (partition by cx_id order by t1.month rows between unbounded preceding and 1 preceding) as prev_avg, sum(cast(isnull(usage,0) as numeric(5,2))) over (partition by cx_id order by t1.month rows between 1 following and unbounded following) as next_sum, avg(cast(isnull(usage,0) as numeric(5,2))) over (partition by cx_id order by t1.month rows between 1 following and unbounded following) as next_avg into #Hold from #test2 t1

select * from #hold where month = 4

给出

  

查询配置文件统计信息INSERT,DELETE和UPDATE的编号   statements 0 0.0000受INSERT,DELETE或UPDATE影响的行   statements 0 0.0000 SELECT语句数3 3.0000行   SELECT语句返回4 4.0000事务数     0 0.0000网络统计服务器数   往返3 3.0000从客户端发送的TDS数据包3 3.0000 TDS   从服务器20收到的数据包20.0000字节发送自   client 1602 1602.0000从服务器72714 72714.0000收到的字节   时间统计客户端处理时间0 0.0000总计   执行时间203 203.0000服务器上的等待时间   回复203 203.0000

0 个答案:

没有答案