我们有一个功能表:
cust_no, cust_loc, feature, toggle, last_udpated_dt
123 ABC DELIVER Y 2019-01-01
123 ABC DELIVER Y 2019-01-03
123 ABC DELIVER N 2019-05-01
123 ABC KEYS N 2019-01-01
123 DEF KEYS N 2019-01-01
123 GHI KEYS N 2019-01-01
123 GHI KEYS Y 2019-02-01
123 GHI KEYS Y 2019-02-04
123 GHI KEYS N 2019-04-01
123 GHI KEYS Y 2019-06-01
有一个后端系统,它为Y / N不同的客户/位置设置了针对不同功能的切换。有效值是last_updated_dt最大的值;
我应该添加,我们经常将'重置'切换到其当前值,因此,如果有人进来并为客户关闭了所有功能/位置,则将为所有功能位置设置标志,即使那些没有位置的标志也将被设置设置,以及关闭的设置;
现在,我被要求评估一段时间内的性能,并且我需要知道何时打开和关闭功能。
我认为最好通过创建这样的表来实现:
cust_no, cust_loc, feature, effective_dt, expiration_dt
123 ABC DELIVER 2019-01-01 2019-05-01
123 GHI KEYS 2019-02-01 2019-04-01
123 GHI KEYS 2019-06-01 9999-12-31
我们可以忽略ABC和DEF中的KEYS标志,因为它们从未打开过。
该种子行将带有最小last_updated_dt:
create table tmp_01 as
select cust_no, cust_loc, feature, min(last_updated_dt) as eff_dt
from feature
where toggle = 'Y'
group by cust_no, cust_loc, feature;
然后我创建一个特征表的副本,其中不包含任何这些行(或第一个Y之前的N个值)
create table tmp_02 as
select cust_no, cust_loc, feature, toggle, last_update_dt
from feature as f
, tmp_01 as a
where a.cust_no = f.cust_no
and a.cust_loc = f.cust_loc
and a.feature = f.feature
and f.last_updated_dt <= eff_dt;
然后我可以在最小last_udated_dt处为每一行创建到期时间,其中toggle = N,创建一个没有这些行的新表
create table tmp_03 as
with f as (select cust_no, cust_loc, feature, min(last_updated_dt) as exp_dt
from tmp_02
where toggle = 'N'
group by cust_no, cust_loc, feature
)
select a.cust_no, a.cust_loc, a.feature, a.eff_dt
, min(coalesce(f.last_updated_dt,'9999-12-31')) as exp_dt
from tmp_01 as a
left outer join f
on (a.cust_no = f.cust_no
and a.cust_loc = f.cust_loc
and a.feature = f.feature)
;
创建功能表(tmp_02)的副本,删除已使用的行:
create table tmp_04 as
select cust_no, cust_loc, feature, toggle, last_update_dt
from tmp_02 as f
, tmp_03 as a
where a.cust_no = f.cust_no
and a.cust_loc = f.cust_loc
and a.feature = f.feature
and f.last_updated_dt <= exp_dt;
现在tmp_03有了我想要的数据,但是只有第一个开/关周期;我将不得不在每个开/关周期重复此操作,直到没有剩余的行了。
似乎应该有一个方法可以在一个周期内完成此操作?我只是看不到。
答案 0 :(得分:0)
我认为lead()
是您想要的:
select t.*,
last_updated_dt as eff_dt,
lead(last_updated_dt) over (partition by cust_no, cust_loc, feature order by last_updated_dt) as end_dt
from t;
这应该为您提供所需的拼贴。
答案 1 :(得分:0)
就像很多问题一样,思考它,然后沉迷于其中。
这是我想出的。 它需要五个步骤,但是无论打开或关闭标志多少次都可以使用。
首先使用英语:
1,我们需要删除多余的行,在这些行中将标志重置为它已经具有的值。
2,如果第一个操作将标志设置为N,则我们将删除所有行
3,我们添加行号,并按字段添加组,以便每对Y / N都可以转换为eff_date,exp_date。
现在输入代码:
create table mww_001 as
select cust_no, cust_loc, feature, toggle, last_updated_date
, lag(toggle_value) over (partition by cust_no, cust_loc, feature
order by last_updated_date) as lag_toggle
from feature_table;
create table mww_002 as
select cust_no, cust_loc, feature, toggle, last_updated_date, lag_toggle
, row_number() over (partition by cust_no, cust_loc, feature
order by last_updated_date) as rownbr_01
from mww_001
where lag_toggle is null or lag_toggle <> toggle;
create table mww_003 as
select cust_no, cust_loc, feature, toggle, last_updated_date
, row_number() over (partition by cust_no, cust_loc, feature
order by last_updated_date) as rownbr_02
from mww_002
where not(rownbr_01 = 1 and toggle = 'N') ;
create table mww_003 as
select cust_no, cust_loc, feature, toggle, last_updated_date
, ceiling(rownbr_02/2) as group_01
from mww_002 ;
create table feature_new as
select cust_no, cust_loc, feature, group_01
, max(case when toggle = 'Y' then last_updated_date else null end) as eff_dt
, coalesce(max(case when toggle = 'N'
then last_updated_date
else null end)
, '9999-12-31') as exp_dt
from mww_003
group by cust_no, cust_loc, feature, group_01 ;