Maison  >  Questions et réponses  >  le corps du texte

Générer un tableau dynamique de tous les mois entre deux dates

<p>我有一个如下所示的表:</p> <table class="s-table"> <tête> <tr> <th>姓名</th> <th>INT_VALUE</th> <th>开始</th> <th>FIN</th> ≪/tr> ≪/tête> <corps> <tr> <td>一个</td> <td>100</td> <td>2013-11-16</td> <td>2014-11-16</td> ≪/tr> </tcorps> </tableau> <p>目标是输出如下:</p> <table class="s-table"> <tête> <tr> <th>姓名</th> <th>INT_VALUE</th> <th>开始</th> <th>FIN</th> <th>间隔</th> ≪/tr> ≪/tête> <corps> <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> </tcorps> </tableau> <p>的开始和结束。</p> <pre class="brush:php;toolbar:false;">SELECT START, calendrier, COUNT(1) DE table1 AS t1 RIGHT JOIN (SELECT row_number() OVER (ORDER BY SEQ4()) AS MOIS , TO_DATE(DATEADD(MOIS, MOIS, '2019-05-01')) AS calendrier DEPUIS TABLE(GÉNÉRATEUR(rowcount=>80))) ON t1.START = calendrier GROUPER PAR 1, 2 COMMANDER PAR 2, 1 ;</pré> <p>
P粉663883862P粉663883862419 Il y a quelques jours531

répondre à tous(2)je répondrai

  • P粉924915787

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

    Déplacé 数字范围 dans son propre CTE pour séparer les choses, nous avons maintenant une grande liste de 80 numéros (probablement plus grande).

    Ensuite, nous trouvons le nombre de mois entre début/fin et joignons le même nombre de lignes. Faites ensuite le calcul pour convertir la plage en sélection :

    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;

    Une autre option consiste à créer une table de dates à long terme

    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))

    Ensuite, nous utilisons BETWEEN pour obtenir les valeurs incluses dans la plage (début, fin), qui devient :

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

    répondre
    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

    Si vous ne voulez pas que le mois ait des zéros non significatifs, utilisez le modèle '%c-%Y'.

    répondre
    0
  • Annulerrépondre