根据 Teradata 中的条件优先级填充列
Populate a column based on conditional precedence in Teradata
我需要根据条件优先级填充列:
如果 O_M
不为零(例如:0.34
),我检查同一列中的 Prev. record
(按 TP_N
排序)O_M
,如果用代码 (OD03,OT03,MO03)
编码的 3 个或更多实例为零,那么我应该用当前 O_M
值 - 0.34
填充 To_Compute
列。我需要对按 TP_N
排序的每个分区 (DT,MNTH,P_ID,A_BR,D_BR,B_BR,DR
) 重复此操作。我应该只从 O_N
- (OD03,OT03,MO03)
列中寻找这些代码
DT MNTH P_ID A_BR D_BR B_BR TP_N DR O_M O_N TO_Compute
9/29/2016 9 QT21 1506 05Y XS-123 487,006 0 0 ? 0
9/29/2016 9 QT21 1506 05Y XS-123 487,007 0 0 OD03 0
9/29/2016 9 QT21 1506 05Y XS-123 487,008 0 0 OD03 0
9/29/2016 9 QT21 1506 05Y XS-123 487,009 0 0 OD03 0
9/29/2016 9 QT21 1506 05Y XS-123 487,010 0 0 OD03 0
9/29/2016 9 QT21 1506 05Y XS-123 487,011 0 0 OD03 0
9/29/2016 9 QT21 1506 05Y XS-123 487,012 0 0 OD03 0
9/29/2016 9 QT21 1506 05Y XS-123 487,013 0 0 OD03 0
9/29/2016 9 QT21 1506 05Y XS-123 487,014 0 0 MO03 0
9/29/2016 9 QT21 1506 05Y XS-123 487,015 0 0 OT03 0
9/29/2016 9 QT21 1506 05Y XS-123 487,016 0 0 OD03 0
9/29/2016 9 QT21 1506 05Y XS-123 487,017 0 0.34 ? 0.34
9/29/2016 9 QT21 1506 05Y XS-123 487,018 0 0 OD03 0
9/29/2016 9 QT21 1506 05Y XS-123 487,019 0 1.03 ? 0
9/29/2016 9 QT21 1506 05Y XS-123 487,020 0 0.3 ? 0
9/29/2016 9 QT21 1506 05Y XS-123 487,021 0 1.25 ? 0
9/29/2016 9 QT21 1506 05Y XS-123 487,022 0 0 OP04 0
9/29/2016 9 QT21 1506 05Y XS-123 487,023 0 10.53 ? 0
9/29/2016 9 QT21 1506 05Y XS-123 487,024 0 0.37 ? 0
9/29/2016 9 QT21 1506 05Y XS-123 487,025 0 0.28 ? 0
9/29/2016 9 QT21 1506 05Y XS-123 487,026 0 0 OD03 0
9/29/2016 9 QT21 1506 05Y XS-123 487,027 0 0 OD03 0
9/29/2016 9 QT21 1506 05Y XS-123 487,028 0 0.6 ? 0
9/29/2016 9 QT21 1506 05Y XS-123 487,029 0 0.38 ? 0
9/29/2016 9 QT21 1506 05Y XS-123 487,030 0 0.4 ? 0
9/29/2016 9 QT21 1506 05Y XS-123 487,031 0 0.35 ? 0
9/29/2016 9 QT21 1506 05Y XS-123 487,032 0 0.45 ? 0
9/29/2016 9 QT21 1506 05Y XS-123 487,033 0 0 OD03 0
9/29/2016 9 QT21 1506 05Y XS-123 487,034 0 0 OD03 0
9/29/2016 9 QT21 1506 05Y XS-123 487,035 0 0 OD03 0
9/29/2016 9 QT21 1506 05Y XS-123 487,036 0 0.3 ? 0.3
9/29/2016 9 QT21 1506 05Y XS-123 487,037 0 0.35 ? 0
9/29/2016 9 QT21 1506 05Y XS-123 487,038 0 0.52 ? 0
但是,如果 O_M
不为零(例如:0.6
- O_M
列从底部开始的第 11 行),我检查同一列中的 Prev. record
O_M
并且我只有 2 个 prev 记录为 zero
(对于使用代码 (OD03,OT03,MO03)
编码的 3 个或更多实例,那么我应该用 0
填充 To_Compute
列。
如果 O_M
不为零(例如:0.3
O_M
的倒数第三行),我检查同一列中的 Prev. record
O_M
在这里,对于使用代码 (OD03,OD03,OD03)
编码的 3 个或更多实例,它为零,那么我应该使用当前 O_M
值 - 0.3
填充 To_Compute
列。
我是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
我将提供两种可能的解决方案,供您决定哪种最适合您的情况。第一个更简单,但更乏味,因为它只是连接同一个 table 3 次。假设您上面的数据存在于 DATASET table:
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_M
不为零(例如:0.34
),我检查同一列中的 Prev. record
(按 TP_N
排序)O_M
,如果用代码 (OD03,OT03,MO03)
编码的 3 个或更多实例为零,那么我应该用当前 O_M
值 - 0.34
填充 To_Compute
列。我需要对按 TP_N
排序的每个分区 (DT,MNTH,P_ID,A_BR,D_BR,B_BR,DR
) 重复此操作。我应该只从 O_N
- (OD03,OT03,MO03)
DT MNTH P_ID A_BR D_BR B_BR TP_N DR O_M O_N TO_Compute
9/29/2016 9 QT21 1506 05Y XS-123 487,006 0 0 ? 0
9/29/2016 9 QT21 1506 05Y XS-123 487,007 0 0 OD03 0
9/29/2016 9 QT21 1506 05Y XS-123 487,008 0 0 OD03 0
9/29/2016 9 QT21 1506 05Y XS-123 487,009 0 0 OD03 0
9/29/2016 9 QT21 1506 05Y XS-123 487,010 0 0 OD03 0
9/29/2016 9 QT21 1506 05Y XS-123 487,011 0 0 OD03 0
9/29/2016 9 QT21 1506 05Y XS-123 487,012 0 0 OD03 0
9/29/2016 9 QT21 1506 05Y XS-123 487,013 0 0 OD03 0
9/29/2016 9 QT21 1506 05Y XS-123 487,014 0 0 MO03 0
9/29/2016 9 QT21 1506 05Y XS-123 487,015 0 0 OT03 0
9/29/2016 9 QT21 1506 05Y XS-123 487,016 0 0 OD03 0
9/29/2016 9 QT21 1506 05Y XS-123 487,017 0 0.34 ? 0.34
9/29/2016 9 QT21 1506 05Y XS-123 487,018 0 0 OD03 0
9/29/2016 9 QT21 1506 05Y XS-123 487,019 0 1.03 ? 0
9/29/2016 9 QT21 1506 05Y XS-123 487,020 0 0.3 ? 0
9/29/2016 9 QT21 1506 05Y XS-123 487,021 0 1.25 ? 0
9/29/2016 9 QT21 1506 05Y XS-123 487,022 0 0 OP04 0
9/29/2016 9 QT21 1506 05Y XS-123 487,023 0 10.53 ? 0
9/29/2016 9 QT21 1506 05Y XS-123 487,024 0 0.37 ? 0
9/29/2016 9 QT21 1506 05Y XS-123 487,025 0 0.28 ? 0
9/29/2016 9 QT21 1506 05Y XS-123 487,026 0 0 OD03 0
9/29/2016 9 QT21 1506 05Y XS-123 487,027 0 0 OD03 0
9/29/2016 9 QT21 1506 05Y XS-123 487,028 0 0.6 ? 0
9/29/2016 9 QT21 1506 05Y XS-123 487,029 0 0.38 ? 0
9/29/2016 9 QT21 1506 05Y XS-123 487,030 0 0.4 ? 0
9/29/2016 9 QT21 1506 05Y XS-123 487,031 0 0.35 ? 0
9/29/2016 9 QT21 1506 05Y XS-123 487,032 0 0.45 ? 0
9/29/2016 9 QT21 1506 05Y XS-123 487,033 0 0 OD03 0
9/29/2016 9 QT21 1506 05Y XS-123 487,034 0 0 OD03 0
9/29/2016 9 QT21 1506 05Y XS-123 487,035 0 0 OD03 0
9/29/2016 9 QT21 1506 05Y XS-123 487,036 0 0.3 ? 0.3
9/29/2016 9 QT21 1506 05Y XS-123 487,037 0 0.35 ? 0
9/29/2016 9 QT21 1506 05Y XS-123 487,038 0 0.52 ? 0
但是,如果 O_M
不为零(例如:0.6
- O_M
列从底部开始的第 11 行),我检查同一列中的 Prev. record
O_M
并且我只有 2 个 prev 记录为 zero
(对于使用代码 (OD03,OT03,MO03)
编码的 3 个或更多实例,那么我应该用 0
填充 To_Compute
列。
如果 O_M
不为零(例如:0.3
O_M
的倒数第三行),我检查同一列中的 Prev. record
O_M
在这里,对于使用代码 (OD03,OD03,OD03)
编码的 3 个或更多实例,它为零,那么我应该使用当前 O_M
值 - 0.3
填充 To_Compute
列。
我是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
我将提供两种可能的解决方案,供您决定哪种最适合您的情况。第一个更简单,但更乏味,因为它只是连接同一个 table 3 次。假设您上面的数据存在于 DATASET table:
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;