在 table 上的两个日期之间动态生成所有月份
Generate all months dynamically between two dates on a table
我有一个 table 这样的:
NAME
INT_VALUE
START
END
One
100
2013-11-16
2014-11-16
目标是这样输出:
NAME
INT_VALUE
START
END
INTERVAL
One
100
2013-11-16
2014-11-16
11-2013
One
100
2013-11-16
2014-11-16
12-2013
One
100
2013-11-16
2014-11-16
1-2014
One
100
2013-11-16
2014-11-16
2-2014
我已经开始使用它了。但我不太确定如何使用 table 上的开始日期和结束日期来确定开始和结束日期,以计算两者之间的月份列表。
SELECT START, calendar, COUNT(1)
FROM table1 AS t1
RIGHT JOIN (SELECT row_number() OVER (ORDER BY SEQ4()) AS MONTHS
, TO_DATE(DATEADD(MONTH, MONTHS, '2019-05-01')) AS calendar
FROM TABLE(GENERATOR(rowcount=>80)))
ON t1.START = calendar
GROUP BY 1, 2
ORDER BY 2, 1
;
此处的目标是将 int 值与范围内从开始到结束的每个月相关联。
WITH RECURSIVE
cte AS ( SELECT name, int_value, start, `end`,
1 rownum, DATE_FORMAT(start, '%m-%Y') `interval`
FROM source_table
UNION ALL
SELECT name, int_value, start, `end`,
1 + rownum, DATE_FORMAT(start + INTERVAL rownum MONTH, '%m-%Y')
FROM cte
WHERE start + INTERVAL rownum - 1 MONTH < `end` )
SELECT name, int_value, start, `end`, `interval`
FROM cte
ORDER BY rownum;
https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=bdd028a7755fdcb8296df2301baeb295
如果您不需要在月份数字前导零,则使用 '%c-%Y'
模式。
所以将 range of numbers
移到它自己的 CTE 中以分离内容,我们现在有一个包含 80 个数字的大列表(可能更大)。
然后我们找到 start/end 之间的月数并加入那么多行。并计算将范围变成 select 部分:
WITH range_of_numbers AS (
SELECT
row_number() OVER (ORDER BY SEQ4())-1 AS rn
FROM TABLE(GENERATOR(rowcount=>80))
)
SELECT
t1.name,
t1.int_value,
t1.start,
t1.end,
DATEADD(MONTH, r.rn, t1.start) as interval
FROM table1 AS t1
JOIN range_of_numbers as r
ON date_diff('month', t1.START, t1.end) <= between r.rn
ORDER BY 2,1,3;
另一种选择是构建一个远程 DATE table
CREATE TABLE dates AS
SELECT
DATEADD(MONTH, row_number() OVER (ORDER BY SEQ4())-1, '1980-01-01') as month_date
FROM TABLE(GENERATOR(rowcount=>8000))
然后我们用BETWEEN得到(start,end)范围内的包含值
会变成:
FROM table1 AS t1
JOIN dates as d
ON d.month_date BETWEEN t1.START AND t1.end
我有一个 table 这样的:
NAME | INT_VALUE | START | END |
---|---|---|---|
One | 100 | 2013-11-16 | 2014-11-16 |
目标是这样输出:
NAME | INT_VALUE | START | END | INTERVAL |
---|---|---|---|---|
One | 100 | 2013-11-16 | 2014-11-16 | 11-2013 |
One | 100 | 2013-11-16 | 2014-11-16 | 12-2013 |
One | 100 | 2013-11-16 | 2014-11-16 | 1-2014 |
One | 100 | 2013-11-16 | 2014-11-16 | 2-2014 |
我已经开始使用它了。但我不太确定如何使用 table 上的开始日期和结束日期来确定开始和结束日期,以计算两者之间的月份列表。
SELECT START, calendar, COUNT(1)
FROM table1 AS t1
RIGHT JOIN (SELECT row_number() OVER (ORDER BY SEQ4()) AS MONTHS
, TO_DATE(DATEADD(MONTH, MONTHS, '2019-05-01')) AS calendar
FROM TABLE(GENERATOR(rowcount=>80)))
ON t1.START = calendar
GROUP BY 1, 2
ORDER BY 2, 1
;
此处的目标是将 int 值与范围内从开始到结束的每个月相关联。
WITH RECURSIVE
cte AS ( SELECT name, int_value, start, `end`,
1 rownum, DATE_FORMAT(start, '%m-%Y') `interval`
FROM source_table
UNION ALL
SELECT name, int_value, start, `end`,
1 + rownum, DATE_FORMAT(start + INTERVAL rownum MONTH, '%m-%Y')
FROM cte
WHERE start + INTERVAL rownum - 1 MONTH < `end` )
SELECT name, int_value, start, `end`, `interval`
FROM cte
ORDER BY rownum;
https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=bdd028a7755fdcb8296df2301baeb295
如果您不需要在月份数字前导零,则使用 '%c-%Y'
模式。
所以将 range of numbers
移到它自己的 CTE 中以分离内容,我们现在有一个包含 80 个数字的大列表(可能更大)。
然后我们找到 start/end 之间的月数并加入那么多行。并计算将范围变成 select 部分:
WITH range_of_numbers AS (
SELECT
row_number() OVER (ORDER BY SEQ4())-1 AS rn
FROM TABLE(GENERATOR(rowcount=>80))
)
SELECT
t1.name,
t1.int_value,
t1.start,
t1.end,
DATEADD(MONTH, r.rn, t1.start) as interval
FROM table1 AS t1
JOIN range_of_numbers as r
ON date_diff('month', t1.START, t1.end) <= between r.rn
ORDER BY 2,1,3;
另一种选择是构建一个远程 DATE table
CREATE TABLE dates AS
SELECT
DATEADD(MONTH, row_number() OVER (ORDER BY SEQ4())-1, '1980-01-01') as month_date
FROM TABLE(GENERATOR(rowcount=>8000))
然后我们用BETWEEN得到(start,end)范围内的包含值 会变成:
FROM table1 AS t1
JOIN dates as d
ON d.month_date BETWEEN t1.START AND t1.end