Maison > Questions et réponses > le corps du texte
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
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'
.