Générer un tableau dynamique de tous les mois entre deux dates
P粉663883862
P粉663883862 2023-08-28 12:44:46
0
2
573
<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粉663883862
P粉663883862

répondre à tous(2)
P粉924915787

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
P粉567112391
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'.

Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal