SQL 2008使用group by运行平均值

时间:2016-11-28 14:59:39

标签: sql sql-server-2008 moving-average

所以我有一个包含以下列的表。 我想从positiondate计算一个运行平均值,例如3天后,在dealno上进行分组。 我知道怎么做" case by"但问题是我有大约200个不同的DealNo所以我不想为每笔交易写一个自己的case by子句。

在交易号1上,它的期望输出应该是平均值(149 243 440 + 149 224 446 + 149 243 451)

DealNo      PositionDate    MarketValue
    1   |   2016-11-27  |   149 243 440
    2   |   2016-11-27  |   21 496 418
    3   |   2016-11-27  |   32 249 600
    1   |   2016-11-26  |   149 243 446
    2   |   2016-11-26  |   21 496 418
    3   |   2016-11-26  |   32 249 600
    1   |   2016-11-25  |   149 243 451
    3   |   2016-11-25  |   32 249 600
    2   |   2016-11-25  |   21 496 418
    3   |   2016-11-24  |   32 249 600
    1   |   2016-11-24  |   149 225 582
    2   |   2016-11-24  |   21 498 120
    1   |   2016-11-23  |   149 256 867
    2   |   2016-11-23  |   21 504 181
    3   |   2016-11-23  |   32 253 440
    1   |   2016-11-22  |   149 256 873
    2   |   2016-11-22  |   21 506 840
    3   |   2016-11-22  |   32 253 440
    1   |   2016-11-21  |   149 234 535
    2   |   2016-11-21  |   21 509 179
    3   |   2016-11-21  |   32 253 600

我尝试了下面的脚本,但它不是很有效,因为我的表包含大约300k行和大约200个不同的dealno。 在SQL 2008中有更有效的方法吗?

with cte as (

SELECT ROW_NUMBER() over(order by dealno, positiondate desc) as Rownr,
        dealno,
        positiondate,
        Currency,
        MvCleanCcy
  FROM T1
           )

select 
rownr, positiondate, DealNo, Currency,
mvcleanavg30d = (select avg(MvCleanCcy) from cte2 where Rownr between c.Rownr and c.Rownr+3)

 from cte as c

1 个答案:

答案 0 :(得分:1)

您不需要窗口功能。您可以使用outer apply

执行此操作
select t1.*, tt1.marketvalue_3day
from t1 outer apply
     (select avg(tt1.marketvalue) as marketvalue_3day
      from (select top 3 tt1.*
            from t1 tt1
            where tt1.deal1 = t1.deal1 and
                  tt1.positiondate <= t1.positiondate
            order by tt1.positiondate desc
           ) tt1
     ) tt1;