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

Posted

技术标签:

【中文标题】获取两个日期之间的月份范围【英文标题】:Get range of months between 2 dates 【发布时间】:2021-04-30 11:25:29 【问题描述】:

例如,我们有类似的行

in out
2020-01-01 2020-03-03

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

in out between
2020-01-01 2020-03-03 ["2020-01-01", "2020-02-01", "2020-03-01"]

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

可以有任何一天,但要保持几个月。 我尝试通过explode/posexplode、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;
in out btw
2020-01-01 2020-03-03 ["2020-02-01", "2020-02-01", "2020-02-01", ""]

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

【问题讨论】:

【参考方案1】:

使用横向视图poseexplode获取带有位置编号的行,使用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"]

【讨论】:

是的,dt_in 中需要有一个月的第一天。 Hive 不包含内置的 FIRST_DAY(),所以我使用这里的方法:***.com/questions/29972317/… @ruslan_krivoshein 编辑:简化了一点 也是为了有用:在我的例子中,我省略了COLLECT_LIST 并在GROUP BY 子句中添加了 pos 以获得扩展的月份视图,因此我将它用于所需的聚合.

以上是关于获取两个日期之间的月份范围的主要内容,如果未能解决你的问题,请参考以下文章

如何使用查询获取两个给定日期之间的月份列表?

如何获取带有年份的月份名称和两个日期之间的年份列表

获取两个月份之间的相差的月份

获取两个日期之间的月份

Java获取两个日期之间的所有月份

PHP 如何获取两个时间之间的年和月份及间隔天数 PHP两个日期之间的所有日期