获取两个日期之间的月份范围
Get range of months between 2 dates
例如我们有这样的行
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
在查询中增加月份。我相信有一些方法,但我需要一个指导。
使用横向视图 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"]
例如我们有这样的行
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
在查询中增加月份。我相信有一些方法,但我需要一个指导。
使用横向视图 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"]