【问题标题】:Carry forward values in Hive在 Hive 中继承价值观
【发布时间】:2020-07-16 05:12:47
【问题描述】:

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

这是我的输入表。

下面是我目前尝试的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得到了下面的结果。但是由于前一个日期没有值,因此突出显示的行为空。如何根据最后一个可用值结转该值?

下面是预期的输出。

非常感谢任何帮助。

【问题讨论】:

  • 表格形式比附加图片更好。
  • @热心。著名的。展望未来,我将以表格形式而不是图像形式给出。

标签: sql hive window-functions lag


【解决方案1】:

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

这里是 PostgreSQL 中的 demo,但也应该在 hive 中工作。

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                   |

【讨论】:

  • 感谢热心。顺便说一句,我认为您错过了添加我在问题 (PARTITION BY Col_1,Col_2,Col_3,Col_4) 中提到的分区。您能否将其也添加到您的答案中,因为我们可能会为另一组 Col_1,Col_2,Col_3,Col_4 值集获得相同/不同的日期@zealous
  • 只是好奇——我们不需要在max(Col_Value) over (partition by rn) 中添加PARTITION BY Col_1,Col_2,Col_3,Col_4 吗?它适用于所有场景吗?
  • @SarathAvanavu 如果这是您问题的答案,请接受。
  • 如果在max(Col_Value) over (partition by rn) 中不添加PARTITION BY Col_1,Col_2,Col_3,Col_4,则会给出错误的结果。当我添加这个条件时,它就像一个魅力。谢谢热心。您可以在答案中进行此编辑。同时,我接受了这个答案并加了一个。
【解决方案2】:

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,而不是第二个参数。

【讨论】:

  • 谢谢戈登。像魅力一样工作。加 1
  • @SarathAvanavu 。 . .我认为这是 Hive 更好的解决方案,这就是我回答的原因。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-10-08
  • 2022-11-21
  • 1970-01-01
  • 2023-04-06
  • 2020-09-07
  • 2017-08-17
  • 2015-12-25
相关资源
最近更新 更多