1. 程式人生 > >去重記錄並做成拉鍊表

去重記錄並做成拉鍊表

 

with tmp1 as (
    select
         t1.day
        ,t1.value
        ,row_number() over(order by t1.day) as rn
    from (
        select '2015-01-01' as day, 1 as value union all
        select '2015-02-01' as day, 1 as value union all
        select '2015-05-01' as day, 1 as value union all
        select
'2015-08-01' as day, 2 as value union all select '2015-11-21' as day, 2 as value union all select '2016-01-21' as day, 3 as value union all select '2016-05-21' as day, 3 as value union all select '2016-08-21' as day, 5 as value union all select '2016-11-21' as day, 6 as
value ) t1 ) -- 將記錄按日期排序生成次序列 ,tmp2 as ( select case when t2.day is null then '0001-01-01' else t1.day end as day ,t1.value ,row_number() over(order by case when t2.day is null then '0001-01-01' else t1.day end) as rn from tmp1 t1 left join tmp1 t2 on t1.rn = (t2.rn +
1) where nvl(t1.value,'') <> nvl(t2.value,'') order by day ) -- 通過次序列交錯進行自關聯,並把關聯後兩邊值相等的記錄剔除,然後再次按時間排序,生成新的次序列 select t1.day as start_day ,nvl(date_add(t2.day,-1),'2999-12-31') as end_day ,t1.value as change_value from tmp2 t1 left join tmp2 t2 on t1.rn = (t2.rn - 1) ;

 

+-------------+-------------+---------------+--+
|  start_day  |   end_day   | change_value  |
+-------------+-------------+---------------+--+
| 0001-01-01  | 2015-07-31  | 1             |
| 2015-08-01  | 2016-01-20  | 2             |
| 2016-01-21  | 2016-08-20  | 3             |
| 2016-08-21  | 2016-11-20  | 5             |
| 2016-11-21  | 2999-12-31  | 6             |
+-------------+-------------+---------------+--+