2016-03-03 76 views
0

我需要使用列B,C,D來計算列E & E的前一行...我有示例語句和計算以供參考。請注意,prev(E)是我需要在計算中使用的E的前一個值,但無法使用。在計算中使用前面的sql

+---------------------------------------------------------------------------------------------------------------------------------------+ 
| TransactionDt | total_allotment(B) | invchange(C) | roomssold_flag(D) | available(E) |  samplestatement   | calculation | 
+---------------------------------------------------------------------------------------------------------------------------------------+ 
| 1/1/16  |   5   |  0  |  null  |  5  | E=case when D=null then B  | 5   | 
| 1/2/16  |   5   |  0  |  1   |  4  | E=case when C=0 then prev(E)-D | E=(5-1) | 
| 1/3/16  |   5   |  0  |  0   |  4  | E=case when C=0 then prev(E)-D | E=(4-0) | 
| 1/4/16  |   6   |  1  |  1   |  5  | E=case when C=1 then B-D  | E=(6-1) | 
| 1/5/16  |   6   |  0  |  0   |  5  | E=case when C=0 then prev(E)-D | E=(5-0) | 
| 1/6/16  |   7   |  1  |  1   |  6  | E=case when C=1 then B-D  | E=(7-1) | 
+---------------------------------------------------------------------------------------------------------------------------------------+ 
+0

由什麼從句前?通過之前的TransactionDt? –

+0

是的。示例語句和示例可能對您有所幫助。 – Kash

+0

在1/5/16行,E =(5-2),不應該是E =(5-0),因爲D = 0? –

回答

1

您可以使用FIRST_VALUE()函數與前款獲得privious值:

set dateformat dmy; 
declare @t table (TransactionDt smalldatetime, b int, c int, d int, e int); 
insert into @t (TransactionDt, b, c, d, e) values 
(cast('01.01.2016' as date), 5, 0, null, 5), 
(cast('02.01.2016' as date), 5, 0, 1, 4), 
(cast('03.01.2016' as date), 5, 0, 0, 4), 
(cast('04.01.2016' as date), 6, 1, 1, 5), 
(cast('05.01.2016' as date), 6, 0, 0, 5), 
(cast('06.01.2016' as date), 7, 1, 1, 6); 

select 
    t.* 
    ,first_value(t.e) over(order by t.TransactionDt asc rows 1 preceding) [prevE] 
    ,case t.c 
    when 0 then 
     first_value(t.e) 
     over(order by t.TransactionDt asc rows 1 preceding) 
     - t.d 
    when 1 then 
     t.b - t.d 
    end [calculation] 
from 
    @t t 
order by 
    t.TransactionDt 
; 

測試在MS SQL 2012年

我的Teradata的不是大風扇,但這個應該工作:

select 
    t.e 
    ,sum(t.e) 
    over(order by t.TransactionDt asc rows between 1 preceding and 1 preceding) ePrev 
    ,case t.c 
    when 0 then 
     sum(t.e) 
     over(order by t.TransactionDt asc rows between 1 preceding and 1 preceding) 
     - t.d 
    when 1 then 
     t.b - t.d 
    end calculation 
from 
    (
    select cast('01.01.2016' as date format 'dd.mm.yyyy') TransactionDt, 5 b, 0 c, null d, 5 e from (select 1 x) x 
    union all 
    select cast('02.01.2016' as date format 'dd.mm.yyyy') TransactionDt, 5 b, 0 c, 1 d, 4 e from (select 1 x) x 
    union all 
    select cast('03.01.2016' as date format 'dd.mm.yyyy'), 5, 0, 0, 4 from (select 1 x) x 
    union all 
    select cast('04.01.2016' as date format 'dd.mm.yyyy'), 6, 1, 1, 5 from (select 1 x) x 
    union all 
    select cast('05.01.2016' as date format 'dd.mm.yyyy'), 6, 0, 0, 5 from (select 1 x) x 
    union all 
    select cast('06.01.2016' as date format 'dd.mm.yyyy'), 7, 1, 1, 6 from (select 1 x) x 
) t 
order by 
    t.TransactionDt 
; 
+0

在Teradata中有沒有辦法? – Kash

+0

爲Teradata添加可能的解決方案 –

0

當你需要重新計算時,只要invchange=1你在使用

sum(invchange) 
over (order by TransactionDt 
     rows unbounded preceding) as grp 

invchange似乎是基於從前一行查詢來創建分區組,所以你需要在Dervied表窩it't計算。

現在它的total_allotment值減去累計總和超過roomssold_flag

select t.*, 
    b - sum(coalesce(D,0)) 
     over (partition by grp 
      order by TransactionDt 
      rows unbounded preceding) 
from 
(
    select TransactionDt,b,c,d, 
     sum(c) over (order by TransactionDt rows unbounded preceding) as grp 
    from t 
) as t 

順便說一句,使用0/1標誌,以獲得動態分區類似於RESET WHEN

+0

我想我對此不太清楚。我創建了字段invchange。只要total_allotment會發生變化(基於時間戳),我將有一個用於invchange的標誌1。請注意,這不是累計和。 – Kash

+0

@Kash:「total_allotment」可能會隨着時間而減少嗎?否則,你仍然可以使用它進行分區... – dnoeth

+0

它可能增加或減少。我會告訴你這個問題。總分配並不反映出售房間。只有當某人手動增加或減少庫存時。所以技術上我必須使用分配,直到庫存沒有變化。當庫存發生變化時,我會使用已更改(更新)的記錄來計算可用房間。 – Kash