【问题标题】:How do I find first value in every last 3 months in Hive如何在 Hive 中每 3 个月找到第一个值
【发布时间】:2020-07-22 08:02:08
【问题描述】:

我有一张如下表。

+-------+-------+--------------+---------------+
| Col_1 | Col_2 | Refresh_Date | Refresh_Value |
+-------+-------+--------------+---------------+
| AE    | A1    | 2019-12-01   |             1 |
| AE    | A1    | 2020-01-01   |             3 |
| AE    | A1    | 2020-02-01   |             5 |
| AE    | A1    | 2020-03-01   |             7 |
| AE    | A1    | 2020-04-01   |            12 |
| AE    | A1    | 2020-05-01   |            14 |
| AE    | A1    | 2020-06-01   |            11 |
| AE    | A1    | 2020-07-01   |            15 |
+-------+-------+--------------+---------------+

我需要从最后一个日期开始的最近 3 个月中获取第一个 Refresh_value(基于 Refresh_date),并且应该有 2 个额外的列(GroupRefresh_Value_Min),其中第一列将包含每过去 3 个月的第一个值,另一列的值说明这些日期属于哪个组。

预期输出

+-------+-------+--------------+---------------+-------+-------------------+
| Col_1 | Col_2 | Refresh_Date | Refresh_Value | Group | Refresh_Value_Min |
+-------+-------+--------------+---------------+-------+-------------------+
| AE    | A1    | 2019-12-01   |             1 | Grp3  |                 1 |
| AE    | A1    | 2020-01-01   |             3 | Grp3  |                 1 |
| AE    | A1    | 2020-02-01   |             5 | Grp2  |                 5 |
| AE    | A1    | 2020-03-01   |             7 | Grp2  |                 5 |
| AE    | A1    | 2020-04-01   |            12 | Grp2  |                 5 |
| AE    | A1    | 2020-05-01   |            14 | Grp1  |                14 |
| AE    | A1    | 2020-06-01   |            11 | Grp1  |                14 |
| AE    | A1    | 2020-07-01   |            15 | Grp1  |                14 |
+-------+-------+--------------+---------------+-------+-------------------+

我尝试了下面的代码,它会在当前行中给出上个月第 3 个月的值,但我需要像上面一样的输出。

first_value(Refresh_Value) over (partition by col_1,col_2 order by Refresh_Date ROWS BETWEEN 2 PRECEDING AND CURRENT ROW)

有人可以帮忙吗?

如果有任何问题,请告诉我。

【问题讨论】:

    标签: sql hive partitioning


    【解决方案1】:

    让我解释一下这个方法(微小的细节可能会有所不同):

    1. 获取每行的最后日期
    with data_with_last_dt as (
      select Col_1, Col_2, Refresh_Date, Refresh_Value,
             max(Refresh_Date) over (partition by Col_1, Col_2) as Last_Date
        from target_table
    ),
    
    1. 获取月差并将其除以 3(整数除法)- 您将获得组号
    data_with_group as (
      select Col_1, Col_2, Refresh_Date, Refresh_Value,
             cast(months_between(Last_Date, Refresh_Date) as int) / 3 as Group_Id
        from data_with_last_dt 
    )
    
    1. 在每个组中找到第一个 Refresh_Value
    select Col_1, Col_2, Refresh_Date, Refresh_Value, Group_Id,
           min(Refresh_Value) over(partition by Col_1, Col_2, Group_Id order by Refresh_Date) as Refresh_Value_Min 
      from data_with_group 
    

    【讨论】:

    • 第 3 点中的 min 并不总是有效。我改用first_value 函数。但是您的整体方法很好,我能够看到预期的结果。接受这个答案。非常感谢!
    【解决方案2】:

    首先找到组:

    tbl1:
    select col1, col2, refrech_date, refresh_value,
           cast((row_number() over (partition by col1, col2 order by refresh_date desc)/3 as int) as group
      from table
    

    然后找到最小值

    tbl2:
    select col1, col2, refrech_date, refresh_value, group
      from tbl1
     where refresh_date = min(refresh_date) over (partition by col1, col2, group)
    

    然后加入最小值

    tbl3:
    select t1.col1, t1.col2, t1.refrech_date, t1.refresh_value, t1.group, t2.refresh_value as refresh_value_min
      from tbl1 t1
      join tbl2 t2
        on(t1.col1 = t2.col1 and t1.col2 = t2.col2 and t1.group = t2.group)
    

    【讨论】:

      猜你喜欢
      • 2021-08-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多