MYSQL 插入缺少日期的行
MYSQL inserting rows with missing dates
我有一个包含两列的 table:
名字
日期
AA
2021-06-01
BB
2021-06-02
CC
2021-05-28
我想编写一个代码来添加具有名称和日期的行,直到今天 (2021-06-03) 日期,如下所示:
名字
日期
AA
2021-06-01
AA
2021-06-02
AA
2021-06-03
BB
2021-06-02
BB
2021-06-03
CC
2021-05-28
CC
2021-05-29
CC
2021-05-30
CC
2021-05-31
CC
2021-06-01
CC
2021-06-02
CC
2021-06-03
我没有使用过递归函数,所以不确定这里最好的做法是什么。任何正确方向的帮助或指示将不胜感激。谢谢:)
对于 MySQL 的最新版本,您可以...
DROP TABLE IF EXISTS my_table;
CREATE TABLE my_table
(name CHAR(2) NOT NULL
,date DATE NOT NULL
,PRIMARY KEY(name,date)
);
INSERT INTO my_table VALUES
('AA','2021-06-01'),
('BB','2021-06-02'),
('CC','2021-05-28');
WITH RECURSIVE cte AS
(
SELECT MIN(date) date FROM my_table
UNION ALL
SELECT date + INTERVAL 1 DAY
FROM cte
WHERE date + INTERVAL 1 DAY <= '2021-06-03'
)
SELECT x.name
, cte.date
FROM my_table x
JOIN cte
ON cte.date >= x.date
ORDER
BY name
, date
| name | date |
| ---- | ---------- |
| AA | 2021-06-01 |
| AA | 2021-06-02 |
| AA | 2021-06-03 |
| BB | 2021-06-02 |
| BB | 2021-06-03 |
| CC | 2021-05-28 |
| CC | 2021-05-29 |
| CC | 2021-05-30 |
| CC | 2021-05-31 |
| CC | 2021-06-01 |
| CC | 2021-06-02 |
| CC | 2021-06-03 |
---
[View on DB Fiddle](https://www.db-fiddle.com/f/wL3ZqXoTqdKftJCPA4um4j/1)
对于旧版本,您可以使用实用程序 table。例如,我有一个 table 的整数 (i),其值从 0 到 9...
SELECT y.name
, x.date
FROM
( SELECT MIN(date) + INTERVAL i DAY date FROM my_table,ints GROUP BY i HAVING date <= '2021-06-03' ) x
JOIN my_table y
ON y.date <= x.date
ORDER
BY name
, date;
+------+------------+
| name | date |
+------+------------+
| AA | 2021-06-01 |
| AA | 2021-06-02 |
| AA | 2021-06-03 |
| BB | 2021-06-02 |
| BB | 2021-06-03 |
| CC | 2021-05-28 |
| CC | 2021-05-29 |
| CC | 2021-05-30 |
| CC | 2021-05-31 |
| CC | 2021-06-01 |
| CC | 2021-06-02 |
| CC | 2021-06-03 |
+------+------------+
您想从 table 中的行到日期 '2021-06-03'
生成行。您可以直接使用递归 CTE 执行此操作:
with recursive cte as (
select name, date
from t
union all
select name, date + interval 1 day
from cte
where date < '2021-06-03'
)
select *
from cte
order by name, date;
Here 是一个 db<>fiddle.
您可以将递归 CTE 解读为:
- 从给定 table 中的行开始。
- 在日期上加一天。
- 当日期为结束日期时停止。
这不仅比“生成所有日期”然后加入更简单,而且应该更快。
我有一个包含两列的 table:
名字 | 日期 |
---|---|
AA | 2021-06-01 |
BB | 2021-06-02 |
CC | 2021-05-28 |
我想编写一个代码来添加具有名称和日期的行,直到今天 (2021-06-03) 日期,如下所示:
名字 | 日期 |
---|---|
AA | 2021-06-01 |
AA | 2021-06-02 |
AA | 2021-06-03 |
BB | 2021-06-02 |
BB | 2021-06-03 |
CC | 2021-05-28 |
CC | 2021-05-29 |
CC | 2021-05-30 |
CC | 2021-05-31 |
CC | 2021-06-01 |
CC | 2021-06-02 |
CC | 2021-06-03 |
我没有使用过递归函数,所以不确定这里最好的做法是什么。任何正确方向的帮助或指示将不胜感激。谢谢:)
对于 MySQL 的最新版本,您可以...
DROP TABLE IF EXISTS my_table;
CREATE TABLE my_table
(name CHAR(2) NOT NULL
,date DATE NOT NULL
,PRIMARY KEY(name,date)
);
INSERT INTO my_table VALUES
('AA','2021-06-01'),
('BB','2021-06-02'),
('CC','2021-05-28');
WITH RECURSIVE cte AS
(
SELECT MIN(date) date FROM my_table
UNION ALL
SELECT date + INTERVAL 1 DAY
FROM cte
WHERE date + INTERVAL 1 DAY <= '2021-06-03'
)
SELECT x.name
, cte.date
FROM my_table x
JOIN cte
ON cte.date >= x.date
ORDER
BY name
, date
| name | date |
| ---- | ---------- |
| AA | 2021-06-01 |
| AA | 2021-06-02 |
| AA | 2021-06-03 |
| BB | 2021-06-02 |
| BB | 2021-06-03 |
| CC | 2021-05-28 |
| CC | 2021-05-29 |
| CC | 2021-05-30 |
| CC | 2021-05-31 |
| CC | 2021-06-01 |
| CC | 2021-06-02 |
| CC | 2021-06-03 |
---
[View on DB Fiddle](https://www.db-fiddle.com/f/wL3ZqXoTqdKftJCPA4um4j/1)
对于旧版本,您可以使用实用程序 table。例如,我有一个 table 的整数 (i),其值从 0 到 9...
SELECT y.name
, x.date
FROM
( SELECT MIN(date) + INTERVAL i DAY date FROM my_table,ints GROUP BY i HAVING date <= '2021-06-03' ) x
JOIN my_table y
ON y.date <= x.date
ORDER
BY name
, date;
+------+------------+
| name | date |
+------+------------+
| AA | 2021-06-01 |
| AA | 2021-06-02 |
| AA | 2021-06-03 |
| BB | 2021-06-02 |
| BB | 2021-06-03 |
| CC | 2021-05-28 |
| CC | 2021-05-29 |
| CC | 2021-05-30 |
| CC | 2021-05-31 |
| CC | 2021-06-01 |
| CC | 2021-06-02 |
| CC | 2021-06-03 |
+------+------------+
您想从 table 中的行到日期 '2021-06-03'
生成行。您可以直接使用递归 CTE 执行此操作:
with recursive cte as (
select name, date
from t
union all
select name, date + interval 1 day
from cte
where date < '2021-06-03'
)
select *
from cte
order by name, date;
Here 是一个 db<>fiddle.
您可以将递归 CTE 解读为:
- 从给定 table 中的行开始。
- 在日期上加一天。
- 当日期为结束日期时停止。
这不仅比“生成所有日期”然后加入更简单,而且应该更快。