2013-11-21 22 views
1

我有一個要求在SQL實現這一SQL滑動數學

YYYYQ| A | Desired Column 
-------------------------- 
3Q12 | A1 | A1  
4Q12 | A2 | A1 * A2 
1Q13 | A3 | A1 * A2 * A3 
2Q13 | A4 | A1 * A2 * A3 * A4 

我使用的是SQL 2012,並試圖使用分區及以上條款,但是,我沒有看到該產品爲我不有獨特的關鍵分區。

達到此目的的最佳方法是什麼?

+0

是否有一個源表不成?如果是這樣,請顯示架構。 –

回答

1

UPDATE:

如果你需要做的,而不是SUM(產品()),有明顯的聚集沒有內建了點。但是,根據this answer和一點row_number()魔術,我們仍然可以達到預期的結果。我有一種感覺,可能有更聰明/更快的方式來做到這一點,或許使用Common Table Expressions,但我不知道那會是什麼。

select 
    the_date, 
    some_value, 
    (
     select exp(sum(log(some_value))) 
     from (
      select *, row_number() over (order by the_date, id) as row_num 
      from #tmp 
     ) y 
     where y.row_num <= a.row_num 
    ) as running_product 
from 
    (
     select *, row_number() over (order by the_date, id) as row_num 
     from #tmp t 
    ) a 
order by 
    the_date, 
    id 

以前的答案:

最簡單的方法來做到這一點是有sum() over像這樣:

if object_id('tempdb..#tmp') is not null drop table #tmp 
create table #tmp (
    id int identity(1,1) not null, 
    the_date datetime not null, 
    some_value decimal(12,2) not null 
) 

insert into #tmp (
    the_date, 
    some_value 
) 
select '1/1/2013', rand() * 100 union all 
select '2/1/2013', rand() * 100 union all 
select '3/1/2013', rand() * 100 union all 
select '4/1/2013', rand() * 100 union all 
select '5/1/2013', rand() * 100 union all 
select '6/1/2013', rand() * 100 

select id, the_date, some_value, 
sum(some_value) over (order by the_date, id) as total 
from #tmp 

如果你需要聚合:

select 
    the_date, 
    some_value_sum, 
    sum(some_value_sum) over (order by the_date) total 
from (
    select the_date, sum(some_value) as some_value_sum 
    from #tmp 
    group by the_date 
) x 
+0

感謝mattmc3的迴應。您的解決方案將順序添加some_value到下一個,但是,我正在尋找的是滑動產品。 A1 * A2,A1 * A2 * A3等 – vmanne

0

所以,這是我的完成解決問題。

declare @test table(id INT IDENTITY(1, 1), value float, yyyyq varchar(5)); 

insert into @test 
select 1.23, '20121' union all 
select 2.23, '20122' union all 
select 3.23, '20123' union all 
select 4.23, '20124' 

select 
    id, 
yyyyq, 
    value a, 
exp(nullif(sign_min, 0) * sum_log) as cumuVal, 
(exp(nullif(sign_min, 0) * sum_log)-1) * 100 as FinalVal 
from @test a 
cross apply 
(select 
sum(coalesce(log(nullif(b.value,0)),0)) as sum_log, 
max(sign(abs(b.value))) as sign_Min 
from @test b 
where b.yyyyq <= a.yyyyq 
) xa1 
order by a.yyyyq 

順便說一句,這是一個使用CTE一個很好的解決方案,但是,這一個獨特的價值(或唯一的ID在該示例)

http://jingyangli.wordpress.com/2012/08/27/a-sliding-aggregate-multiply-code-sample-rows-between-1-preceding-and-current-row/