mySQL - 在日期之间生成额外的行

时间:2016-04-22 16:15:21

标签: mysql

我有一张如下表格。

id     month     duration
001    1/1/16    3
002    3/1/16    4
003    12/1/15   2   

我想在显示指定数量减去1的月份之后的每个月向表中添加一个新行,例如下面:

id     month    duration
001    1/1/16   3
001    2/1/16   3
001    3/1/16   3
002    3/1/16   4
002    4/1/16   4
002    5/1/16   4
002    6/1/16   4
003    12/1/15  2
003    1/1/16   2

依此类推,同时复制未显示的任何列中的值。

我在R中完成了这个,我首先填充了'短'数据,然后将其重新整形为长,但在网上搜索后,我仍然不知道如何在mySQL中执行此操作。在此先感谢您的帮助!

2 个答案:

答案 0 :(得分:0)

如果你可以在MySQL中自动生成很容易的行;除了你不能。不过,您可以使用here描述的技术生成一些行,然后使用JOIN获取所需的数据:

-- Create a VIEW with 16 dummy rows
CREATE OR REPLACE VIEW generator_16
AS SELECT 0 n UNION ALL SELECT 1  UNION ALL SELECT 2  UNION ALL 
   SELECT 3   UNION ALL SELECT 4  UNION ALL SELECT 5  UNION ALL
   SELECT 6   UNION ALL SELECT 7  UNION ALL SELECT 8  UNION ALL
   SELECT 9   UNION ALL SELECT 10 UNION ALL SELECT 11 UNION ALL
   SELECT 12  UNION ALL SELECT 13 UNION ALL SELECT 14 UNION ALL 
   SELECT 15;

拥有此生成器后,您的查询将变为:

SELECT id, date_add(month, INTERVAL n MONTH), duration
FROM tbl
INNER JOIN generator_16 ON n < duration
ORDER BY id, month

我假设您的表结构如下:

CREATE TABLE tbl(id varchar(10), month date, duration int);
INSERT INTO tbl VALUES('001', '2016-01-01', 3);
INSERT INTO tbl VALUES('002', '2016-03-01', 4);
INSERT INTO tbl VALUES('003', '2015-12-01', 2);

答案 1 :(得分:0)

数据显示的问题通常最好在表示层中解决(例如简单的PHP循环),但只是为了好玩......

DROP TABLE IF EXISTS my_table;

CREATE TABLE my_table
(id INT NOT NULL AUTO_INCREMENT PRIMARY KEY
,dt DATE NOT NULL
,duration INT NOT NULL
);

INSERT INTO my_table VALUES
(1,'2016-01-01',3),
(2,'2016-03-01',4),
(3,'2015-12-01',2);   

SELECT * FROM my_table;
+----+------------+----------+
| id | dt         | duration |
+----+------------+----------+
|  1 | 2016-01-01 |        3 |
|  2 | 2016-03-01 |        4 |
|  3 | 2015-12-01 |        2 |
+----+------------+----------+

SELECT * FROM ints;
+---+
| i |
+---+
| 0 |
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
| 6 |
| 7 |
| 8 |
| 9 |
+---+

 SELECT x.id,x.dt + INTERVAL y.i MONTH,x.duration FROM my_table x JOIN ints y ON y.i < x.duration;
+----+---------------------------+----------+
| id | x.dt + INTERVAL y.i MONTH | duration |
+----+---------------------------+----------+
|  1 | 2016-01-01                |        3 |
|  1 | 2016-02-01                |        3 |
|  1 | 2016-03-01                |        3 |
|  2 | 2016-03-01                |        4 |
|  2 | 2016-04-01                |        4 |
|  2 | 2016-05-01                |        4 |
|  2 | 2016-06-01                |        4 |
|  3 | 2015-12-01                |        2 |
|  3 | 2016-01-01                |        2 |
+----+---------------------------+----------+