Impala/Hive 类似于 LOCF 的缺失值填充(上次观察结转)

Impala/Hive Filling in Missing Values Similar to LOCF (last observation carry forward)

我有 Impala 这种格式的时间序列数据。

当且仅当发生更改时才会创建一条记录,更新后的值代表新数据。

---------------------------------------
| Product | Year | Week | UpdatedValue |
---------------------------------------
|A        | 2017 | 1    | 5            |
|A        | 2017 | 5    | 10           |
|A        | 2017 | 20   | 80           |
|B        | 2017 | 8    | 90           |
|...      | ...  | ...  | ...          |
---------------------------------------

假设我们的时间 window 是 2017 年全年从第一周到第 52 周。上面的数据表明产品 A 在第一周的值更改为 5,第 5 周到第 10 周和第 20 周是 80。我想用最后一次观察结转逻辑来填充缺失值,如果数据不是从第一周开始的,那么也用下一个填充前导缺失值发生。

这应该是理想的输出。

---------------------------------------
| Product | Year | Week | UpdatedValue |
---------------------------------------
|A        | 2017 | 1    | 5            |
|A        | 2017 | .    | 5            |
|A        | 2017 | 4    | 5            |
|A        | 2017 | 5    | 10           |
|A        | 2017 | 6    | 10           |
|A        | 2017 | .    | 10           |
|A        | 2017 | 20   | 80           |
|A        | 2017 | .    | 80           |
|A        | 2017 | 52   | 80           |
|B        | 2017 | 1    | 90           |
|B        | 2017 | .    | 90           |
|B        | 2017 | 8    | 90           |
|B        | 2017 | .    | 90           |
|B        | 2017 | 52   | 90           |
|...      | ...  | ...  | ...          |
---------------------------------------

是否有可行的解决方案Hive/Impala如果更容易的话,您一定可以使用他们的高级分析功能吗?但是,如果有通用的 SQL 解决方案可用,那就太好了。

第一步: 用数字创建 table。

create table if not exists tblNumbers
location 'hdfs_location' as 
select 1 as num
union all 
select 2 as num
....

第 2 步: 交叉连接唯一产品,使用数字年份并左连接原始 table 以生成产品缺失的行。然后使用 运行 求和逻辑生成组以对连续的缺失值行进行分组,之后您可以使用 max 从最后找到的值生成缺失行的值。

select product,year,week,max(val) over(partition by product,year,grp) as new_val
from (select py.product,py.year,n.week,t.val
      ,sum(case when t.val is not null then 1 else 0 end) 
       over(partition by py.product,py.year order by n.week) as grp
      from tblNumbers n
      cross join (select distinct product,year from tbl) py
      left join tbl t on n.week = t.week and py.product = t.product and py.year = t.year
     ) t