基于Teradata中的条件优先级填充列

基于Teradata中的条件优先级填充列,teradata,partition,operator-precedence,Teradata,Partition,Operator Precedence,我需要根据条件优先级填充列: 如果O_M不是零(例如:0.34),我检查Prev。将(按TP_N排序)记录在同一列O_M中,如果使用代码(OD03,OT03,MO03)编码的3个或更多实例的值为零,则我应该使用当前的O_M值填充以计算列。我需要对由TP\u N排序的每个分区(DT,MNTH,P\u ID,A\u BR,D\u BR,B\u BR,DR)重复此操作。我应该只从列O\u N-(OD03、OT03、MO03) 但是,如果O_M不是零(例如:0.6-列O_M从底部算起的第11行),我检查

我需要根据条件优先级填充列:

如果
O_M
不是零(例如:
0.34
),我检查
Prev。将
(按
TP_N
排序)记录在同一列
O_M
中,如果使用代码
(OD03,OT03,MO03)
编码的3个或更多实例的值为零,则我应该使用当前的
O_M
值填充
以计算列
。我需要对由
TP\u N
排序的每个分区(
DT,MNTH,P\u ID,A\u BR,D\u BR,B\u BR,DR)重复此操作。我应该只从列
O\u N
-
(OD03、OT03、MO03)

但是,如果
O_M
不是零(例如:
0.6
-列
O_M
从底部算起的第11行),我检查
Prev。记录
在同一列
O_M
中,我只有两个以前的记录作为
zero
(对于使用代码
(OD03,OT03,MO03)编码的3个或更多实例
,那么我应该填充
以使用
0
计算列

如果
O_M
不是零(例如
O_M
0.3
最后第三行),我检查同一列
O_M
中的
Prev.record
,在这里用代码
编码的3个或更多实例为零(OD03,OD03,OD03)
然后我应该用当前
O\u M
值填充
以计算
列-
0.3


我是TD新手。对这方面的任何了解都会有所帮助。

未经测试,但根据您的描述,这应该是可行的:

case
   when sum(O_M) -- previous three rows are all 0 (assuming no negative values exist)
        over (partition by ??
              order by TP_N
              rows between 3 preceding and 1 preceding) = 0
    and -- prvious three rows contain any of the searched codes
        sum(case when O_N IN ('OD03','OT03','MO03') then 1 else 0 end)
        over (partition by ??
              order by TP_N
              rows between 3 preceding and 1 preceding) = 3
   then O_M
   else 0
end

我将为您提供两种可能的解决方案,以决定哪种方案最适合您的情况。第一种方案更简单,但更繁琐,因为它只会连接到同一个表3次。假设上面的数据存在于DATASET表中:

select ds1.dt
,ds1.mnth
,ds1.p_id
,ds1.a_br
,ds1.d_br
,ds1.b_br
,ds1.tp_n
,ds1.dr
,ds1.o_m
,ds1.o_n
,case when zeroifnull(ds4.o_m) + zeroifnull(ds3.o_m) + zeroifnull(ds2.o_m) = 0 and ds4.o_n in ('OD03','OT03','MO03') and ds3.o_n in ('OD03','OT03','MO03') and ds2.o_n in ('OD03','OT03','MO03') then ds1.o_m
else 0 end as TO_COMPUTE
from dataset ds1
left join dataset ds2
on ds1.tp_n = ds2.tp_n +1
and ds1.dt = ds2.dt
and ds1.mnth = ds2.mnth
and ds1.p_id = ds2.p_id
and ds1.a_br = ds2.a_br
and ds1.d_br = ds2.d_br
and ds1.b_br = ds2.b_br
and ds1.dr = ds2.dr
left join dataset ds3
on ds1.tp_n = ds3.tp_n +2
and ds1.dt = ds3.dt
and ds1.mnth = ds3.mnth
and ds1.p_id = ds3.p_id
and ds1.a_br = ds3.a_br
and ds1.d_br = ds3.d_br
and ds1.b_br = ds3.b_br
and ds1.dr = ds3.dr
left join dataset ds4
on ds1.tp_n = ds4.tp_n +3
and ds1.dt = ds4.dt
and ds1.mnth = ds4.mnth
and ds1.p_id = ds4.p_id
and ds1.a_br = ds4.a_br
and ds1.d_br = ds4.d_br
and ds1.b_br = ds4.b_br
and ds1.dr = ds4.dr
order by 7;
第二个使用子查询中的分区:

select sub.dt
,sub.mnth
,sub.p_id
,sub.a_br
,sub.d_br
,sub.b_br
,sub.tp_n
,sub.dr
,sub.o_m
,sub.o_n
,case when o_m2 = 0 and o_m3 = 0 and o_m4 = 0 and o_n2 in ('OD03','OT03','MO03') and o_n4 in ('OD03','OT03','MO03') and o_n4 in ('OD03','OT03','MO03') then sub.o_m
else 0 end as TO_COMPUTE
from
(
select ds.dt
,ds.mnth
,ds.p_id
,ds.a_br
,ds.d_br
,ds.b_br
,ds.tp_n
,ds.dr
,ds.o_m
,ds.o_n
,max(ds.o_m) over (partition by ds.dt, ds.mnth, ds.p_id, ds.a_br, ds.d_br, ds.b_br, ds.dr order by ds.tp_n rows between 1 preceding and 1 preceding) as O_M2
,max(ds.o_m) over (partition by ds.dt, ds.mnth, ds.p_id, ds.a_br, ds.d_br, ds.b_br, ds.dr order by ds.tp_n rows between 2 preceding and 2 preceding) as O_M3
,max(ds.o_m) over (partition by ds.dt, ds.mnth, ds.p_id, ds.a_br, ds.d_br, ds.b_br, ds.dr order by ds.tp_n rows between 3 preceding and 3 preceding) as O_M4
,max(ds.o_n) over (partition by ds.dt, ds.mnth, ds.p_id, ds.a_br, ds.d_br, ds.b_br, ds.dr order by ds.tp_n rows between 1 preceding and 1 preceding) as O_N2
,max(ds.o_n) over (partition by ds.dt, ds.mnth, ds.p_id, ds.a_br, ds.d_br, ds.b_br, ds.dr order by ds.tp_n rows between 2 preceding and 2 preceding) as O_N3
,max(ds.o_n) over (partition by ds.dt, ds.mnth, ds.p_id, ds.a_br, ds.d_br, ds.b_br, ds.dr order by ds.tp_n rows between 3 preceding and 3 preceding) as O_N4
from dataset ds
) sub
order by 7;

列O_N中的代码是否必须按特定顺序排列,并且所有三个都必须存在?如果3个或更多上一个连续记录为零,则我检查O_N列,它必须在这三个代码内。(无空)。无特定顺序。根据我的经验,您不能在“when”中使用窗口函数是案例陈述的一部分,但你可以在“then”部分使用。@M.Wise:当你可以在中使用它时,你也可以在When或ELSE中使用它:-)我昨天确认过。您在WHEN中出现“非法使用Case”错误,而在WHEN中运行良好。@M.Wise:嗯,我一直都在这样做,这一定是其他原因。您能分享失败的部分吗?@dnoeth工作得很好。我正在检查场景。然而,对于发布的问题,我得到了预期的结果
select sub.dt
,sub.mnth
,sub.p_id
,sub.a_br
,sub.d_br
,sub.b_br
,sub.tp_n
,sub.dr
,sub.o_m
,sub.o_n
,case when o_m2 = 0 and o_m3 = 0 and o_m4 = 0 and o_n2 in ('OD03','OT03','MO03') and o_n4 in ('OD03','OT03','MO03') and o_n4 in ('OD03','OT03','MO03') then sub.o_m
else 0 end as TO_COMPUTE
from
(
select ds.dt
,ds.mnth
,ds.p_id
,ds.a_br
,ds.d_br
,ds.b_br
,ds.tp_n
,ds.dr
,ds.o_m
,ds.o_n
,max(ds.o_m) over (partition by ds.dt, ds.mnth, ds.p_id, ds.a_br, ds.d_br, ds.b_br, ds.dr order by ds.tp_n rows between 1 preceding and 1 preceding) as O_M2
,max(ds.o_m) over (partition by ds.dt, ds.mnth, ds.p_id, ds.a_br, ds.d_br, ds.b_br, ds.dr order by ds.tp_n rows between 2 preceding and 2 preceding) as O_M3
,max(ds.o_m) over (partition by ds.dt, ds.mnth, ds.p_id, ds.a_br, ds.d_br, ds.b_br, ds.dr order by ds.tp_n rows between 3 preceding and 3 preceding) as O_M4
,max(ds.o_n) over (partition by ds.dt, ds.mnth, ds.p_id, ds.a_br, ds.d_br, ds.b_br, ds.dr order by ds.tp_n rows between 1 preceding and 1 preceding) as O_N2
,max(ds.o_n) over (partition by ds.dt, ds.mnth, ds.p_id, ds.a_br, ds.d_br, ds.b_br, ds.dr order by ds.tp_n rows between 2 preceding and 2 preceding) as O_N3
,max(ds.o_n) over (partition by ds.dt, ds.mnth, ds.p_id, ds.a_br, ds.d_br, ds.b_br, ds.dr order by ds.tp_n rows between 3 preceding and 3 preceding) as O_N4
from dataset ds
) sub
order by 7;