在 Hive 中继承值

Carry forward values in Hive

我需要根据最后一个 Col_Date 结转 Col_Value 的值(基于列 Col_1,Col_2,Col_3,Col_4 上的逻辑分区)。当当前行中有值时,我们不应结转并使用当前值,否则从上一个日期结转。如果当前行和上一个日期都没有值,那么我们应该使用最近的结转值。

这是我的输入 table。

下面是我目前试过的sql。

select *,
case 
    when col_value is null 
        then lag(Col_Value) over (PARTITION BY Col_1,Col_2,Col_3,Col_4 order by Col_Date) 
    else col_value
end as Carry_Fowrard_Value
from carry_table

我使用了 lag 分析函数,并根据上面分享的 sql 得到了以下结果。但是由于前一个日期没有值,所以突出显示的行我得到了空值。如何根据上一个可用值结转值?

下面是预期的输出。

非常感谢任何帮助。

尝试以下操作 - 首先获取 NULL 值的计数,然后用该分区内的 max() 值填充这些空值。

虽然这是 PostgreSQL 中的 demo,但在配置单元中应该也能正常工作。

select
  Col_1, 
  Col_2, 
  Col_3, 
  Col_4, 
  Col_Date,
  Col_Value,
  coalesce(Col_Value, max(Col_Value) over (partition by Col_1, Col_2, Col_3, Col_4, rn)) as Carry_Forward_Value
from
(
  select
      *,
      count(Col_Value) over (partition by Col_1, Col_2, Col_3, Col_4 order by Col_Date) as rn
  from carry_table
) subq

输出:

| col_1 | col_2 | col_3 | col_4 | col_date   | col_value | carry_forward_value |
| ----- | ----- | ----- | ----- | ---------- | --------- | ------------------- |
| ES    | A1    | X1    | Y1    | 2019-12-31 | 0         | 0                   |
| ES    | A1    | X1    | Y1    | 2020-01-01 |           | 0                   |
| ES    | A1    | X1    | Y1    | 2020-01-31 | 3         | 3                   |
| ES    | A1    | X1    | Y1    | 2019-02-01 | 4         | 4                   |
| ES    | A1    | X1    | Y1    | 2019-03-31 |           | 4                   |
| ES    | A1    | X1    | Y1    | 2019-02-29 |           | 4                   |
| ES    | A1    | X1    | Y1    | 2019-03-01 |           | 4                   |
| ES    | A1    | X1    | Y1    | 2019-04-01 | 6         | 6                   |
| ES    | A1    | X1    | Y1    | 2019-04-30 |           | 6                   |

Hive 支持忽略 FIRST_VALUE()LAST_VALUES() 上的 NULL 值。唉,它在 LAG() 上不支持这个,但是你可以使用 LAST_VALUE():

select ct.*,
       last_value(Col_Value, TRUE) over (partition by Col_1, Col_2, Col_3, Col_4 order by Col_Date)
from carray_table ct;

这应该完全符合您的要求,无需子查询。

注意:Hive 语法是非标准的。标准语法是 IGNORE NULLS,而不是第二个参数。