使用 MySQL8.0 你可以这样做:
WITH RECURSIVE cte AS (
SELECT
ID,
MONTH(StartDate) as M,
MONTHNAME(StartDate) as MonthName,
1 as X
FROM fromto
UNION ALL
SELECT
cte.ID,
MONTH(DATE_ADD(StartDate,INTERVAL X MONTH)),
MONTHNAME(DATE_ADD(StartDate,INTERVAL X MONTH)),
X+1
FROM cte
INNER JOIN fromto on fromto.ID=cte.ID
WHERE DATE_ADD(StartDate,INTERVAL X MONTH)<=EndDate
)
SELECT ID,M,MonthName FROM cte order by ID,M;
输出:
+------+------+-----------+
| ID | M | MonthName |
+------+------+-----------+
| 1 | 1 | January |
| 1 | 2 | February |
| 1 | 3 | March |
| 1 | 4 | April |
| 2 | 3 | March |
| 2 | 4 | April |
| 2 | 5 | May |
+------+------+-----------+
上面例子中的表fromto是这样创建的:
CREATE TABLE `fromto` (
`id` int DEFAULT NULL,
`startdate` date DEFAULT NULL,
`enddate` date DEFAULT NULL
);
INSERT INTO `fromto` VALUES (1,'2021-01-01','2021-04-01'),(2,'2021-03-01','2021-05-01');
如果没有WITH(在 MySQL 8.0 之前),可以这样做:
DROP TABLE IF EXISTS counter;
CREATE TABLE counter(i int primary key);
INSERT INTO counter VALUES (0),(1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12);
SELECT
id,
MONTHNAME(DATE_ADD(StartDate,INTERVAL i MONTH))
FROM
fromto
CROSS JOIN counter
WHERE DATE_ADD(StartDate,INTERVAL i MONTH)<=EndDate
ORDER BY id,2;
应将所需的值添加到此counter 表中。