首页  >  问答  >  正文

生成两个日期之间的所有月份的动态表格

<p>我有一个如下所示的表:</p> <table class="s-table"> <thead> <tr> <th>姓名</th> <th>INT_VALUE</th> <th>开始</th> <th>END</th> </tr> </thead> <tbody> <tr> <td>一个</td> <td>100</td> <td>2013-11-16</td> <td>2014-11-16</td> </tr> </tbody> </table> <p>目标是输出如下:</p> <table class="s-table"> <thead> <tr> <th>姓名</th> <th>INT_VALUE</th> <th>开始</th> <th>END</th> <th>间隔</th> </tr> </thead> <tbody> <tr> <td>一个</td> <td>100</td> <td>2013-11-16</td> <td>2014-11-16</td> <td>11-2013</td> </tr> <tr> <td>一个</td> <td>100</td> <td>2013-11-16</td> <td>2014-11-16</td> <td>2013年12月</td> </tr> <tr> <td>一个</td> <td>100</td> <td>2013-11-16</td> <td>2014-11-16</td> <td>1-2014</td> </tr> <tr> <td>一个</td> <td>100</td> <td>2013-11-16</td> <td>2014-11-16</td> <td>2014年2月</td> </tr> </tbody> </table> <p>我已经开始使用这个。但是我不确定如何使用表中的START和END日期来确定计算之间的月份列表的开始和结束。</p> <pre class="brush:php;toolbar:false;">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 ;</pre> <p>这里的目标是将int值与范围开始到结束之间的每个月份关联起来。</p>
P粉663883862P粉663883862419 天前535

全部回复(2)我来回复

  • P粉924915787

    P粉9249157872023-08-29 11:21:21

    数字范围移至自己的CTE中以分离事物,我们现在有一个包含80个数字的大列表(可能更大)。

    然后我们找到开始/结束之间的月数,并连接相同数量的行。然后进行数学计算,将范围转换为选择部分:

    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;

    另一个选择是构建一个长时间范围的日期表

    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来获取(开始,结束)范围内的包含值,变为:

    FROM table1 AS t1
    JOIN dates as d
        ON d.month_date BETWEEN t1.START AND t1.end

    回复
    0
  • P粉567112391

    P粉5671123912023-08-29 00:50:09

    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'模式。

    回复
    0
  • 取消回复