获取两个日期之间的月份范围

时间:2021-04-30 11:25:29

标签: sql arrays hive hiveql date-range

例如我们有这样的行

<头>
2020-01-01 2020-03-03

并且我需要一个包含月份列表的结果,即:

<头>
之间
2020-01-01 2020-03-03 [“2020-01-01”、“2020-02-01”、“2020-03-01”]

然后按某些分组计算所有月份。

可以有任何一天,但要保留几个月。
我尝试通过组合爆炸/姿势爆炸、months_between、add_months、CTE 来达到这一点,但还缺乏大脑。其中之一:

select
    *,
    case
        when cast(
            ceil(abs(months_between(test.in, test.out))) as int
        ) > 1 then split(
            repeat(
                concat(add_months(test.in, 1), ','),
                cast(
                    ceil(abs(months_between(test.in, test.out))) as int
                )
            ),
            ','
        )
        else array(test.in)
    end btw
from test;
<头>
顺便说一句
2020-01-01 2020-03-03 ["2020-02-01", "2020-02-01", "2020-02-01", ""]

我不知道如何使用 months_between 在查询中增加月份。我相信有一些方法,但我需要一个指针。

1 个答案:

答案 0 :(得分:1)

使用横向视图posexplode获取带有位置编号的行,使用add_months将位置添加到IN日期,collect_list获取数组,必要时使用concat_ws连接数组。

演示:

WITH test AS (
    SELECT '2020-01-06' dt_in, '2020-03-03' dt_out
)
SELECT dt_in, dt_out, 
       COLLECT_LIST(DATE_FORMAT(ADD_MONTHS(t.dt_in, pos), 'yyyy-MM-01')) AS `between`
FROM test t  
LATERAL VIEW OUTER POSEXPLODE(
    SPLIT(
        SPACE(
            CAST(CEIL(ABS(MONTHS_BETWEEN(DATE_FORMAT(t.dt_in, 'yyyy-MM-01'), t.dt_out))) AS INT) - 1
            ),
        ' '
        )
) e AS pos, x  
GROUP BY dt_in, dt_out;

结果:

     dt_in       dt_out       between   

2020-01-01       2020-03-03   ["2020-01-01","2020-02-01","2020-03-01"]