我需要使用B,C,D和B列来计算E列。前一行E ...我有样本陈述和计算供参考。请注意,prev(E)是我在计算中需要使用的E的前一个值,但我无法做到。
+---------------------------------------------------------------------------------------------------------------------------------------+
| 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 :(得分:1)
您可以使用带有前面子句的first_value()函数来获取私有值:
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
;
答案 1 :(得分:0)
当您需要在invchange=1
时重新开始计算时,您必须使用
sum(invchange)
over (order by TransactionDt
rows unbounded preceding) as grp
invchange
似乎基于前一行查询,因此您需要将其嵌套在Dervied Table中。
现在你的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