在 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
,而不是第二个参数。
我需要根据最后一个 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
,而不是第二个参数。