PostgreSQL 提供了一个很强大的造数据的函数generate_series,基于Common Table Expression。
MySQL 没有复杂的应用程序类型,该如何实现这样的功能呢? 我想到的三种方法如下:
1. 用存储过程来做。 缺点是写好多数据库不擅长的应用逻辑。
2. 我们想到MySQL提供了SESSION 变量这样的特性, 可以很方便的完成同样的功能。
3. MariaDB 提供了一种sequence 引擎,也可以方便的做这件事情。
第一种我就不实现了, 我来举例说明后两种。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
表结构如下:
ytt[love]>show
create
table
test_series;
+
-------------+-------------------------------------------------------------------------------------------------------------------------+
|
Table
|
Create
Table
|
+
-------------+-------------------------------------------------------------------------------------------------------------------------+
| test_series |
CREATE
TABLE
`test_series` (
`id`
int
(11)
NOT
NULL
,
`log_date`
date
NOT
NULL
) ENGINE=InnoDB
DEFAULT
CHARSET=latin1 |
+
-------------+-------------------------------------------------------------------------------------------------------------------------+
1 row
in
set
(0.00 sec)
对应的PostgreSQL 运算结果:
t_girl=#
insert
into
test_series
select
seq,
current_date
-
'1 day'
::interval*seq
from
generate_series(1,20)
as
g(seq);
INSERT
0 20
t_girl=#
select
*
from
test_series;
id | log_date
----+------------
1 | 2014-03-02
2 | 2014-03-01
3 | 2014-02-28
4 | 2014-02-27
5 | 2014-02-26
6 | 2014-02-25
7 | 2014-02-24
8 | 2014-02-23
9 | 2014-02-22
10 | 2014-02-21
11 | 2014-02-20
12 | 2014-02-19
13 | 2014-02-18
14 | 2014-02-17
15 | 2014-02-16
16 | 2014-02-15
17 | 2014-02-14
18 | 2014-02-13
19 | 2014-02-12
20 | 2014-02-11
(20
rows
)
|
第一: SESSION 变量。
MySQL 的SESSION 变量来变相实现的话,需要一个种子库。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
|
以下存储过程生成种子库。
DELIMITER $$
USE `t_girl`$$
DROP
PROCEDURE
IF EXISTS `sp_seed`$$
CREATE
DEFINER=`root`@`localhost`
PROCEDURE
`sp_seed`(
IN
f_num
INT
UNSIGNED
)
BEGIN
DROP
TABLE
IF EXISTS tmp_seed;
CREATE
TEMPORARY
TABLE
tmp_seed (id
INT
);
BEGIN
DECLARE
i
INT
;
SET
i = 1;
WHILE i <= f_num DO
INSERT
INTO
tmp_seed
VALUES
(i);
SET
i = i + 1;
END
WHILE;
END
;
END
$$
DELIMITER ;
生成20个种子库
ytt[love]>call sp_seed(20);
Query OK, 1 row affected (0.15 sec)
现在利用刚才的种子库以及SESSION 变量来实现。
ytt[love]>
insert
into
test_series
select
@a := @a + 1
as
seq, date_sub(
current_date
(), interval @a
day
)
from
tmp_seed,(
select
@a:=0)
as
seq;
Query OK, 20
rows
affected (0.02 sec)
Records: 20 Duplicates: 0 Warnings: 0
ytt[love]>
select
*
from
test_series;
+
----+------------+
| id | log_date |
+
----+------------+
| 1 | 2014-03-02 |
| 2 | 2014-03-01 |
| 3 | 2014-02-28 |
| 4 | 2014-02-27 |
| 5 | 2014-02-26 |
| 6 | 2014-02-25 |
| 7 | 2014-02-24 |
| 8 | 2014-02-23 |
| 9 | 2014-02-22 |
| 10 | 2014-02-21 |
| 11 | 2014-02-20 |
| 12 | 2014-02-19 |
| 13 | 2014-02-18 |
| 14 | 2014-02-17 |
| 15 | 2014-02-16 |
| 16 | 2014-02-15 |
| 17 | 2014-02-14 |
| 18 | 2014-02-13 |
| 19 | 2014-02-12 |
| 20 | 2014-02-11 |
+
----+------------+
20
rows
in
set
(0.00 sec)
|
第二:
MySQL(MariaDB ) 提供了一个序列引擎,可以有这样的功能。
由于MySQL 没有表函数功能,所以如果要造多个字段的数据,就得用JOIN来实现了。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
ytt[love]>
insert
into
test_series
select
s1.seq,date_sub(
current_date
(),interval s2.seq
day
)
as
date
from
seq_1_to_20
as
s1, seq_1_to_20
as
s2
where
s1.seq = s2.seq;
Query OK, 20
rows
affected (0.07 sec)
Records: 20 Duplicates: 0 Warnings: 0
ytt[love]>
select
*
from
test_series;
+
----+------------+
| id | log_date |
+
----+------------+
| 1 | 2014-03-02 |
| 2 | 2014-03-01 |
| 3 | 2014-02-28 |
| 4 | 2014-02-27 |
| 5 | 2014-02-26 |
| 6 | 2014-02-25 |
| 7 | 2014-02-24 |
| 8 | 2014-02-23 |
| 9 | 2014-02-22 |
| 10 | 2014-02-21 |
| 11 | 2014-02-20 |
| 12 | 2014-02-19 |
| 13 | 2014-02-18 |
| 14 | 2014-02-17 |
| 15 | 2014-02-16 |
| 16 | 2014-02-15 |
| 17 | 2014-02-14 |
| 18 | 2014-02-13 |
| 19 | 2014-02-12 |
| 20 | 2014-02-11 |
+
----+------------+
20
rows
in
set
(0.00 sec)
|
本文转自 david_yeung 51CTO博客,原文链接:http://blog.51cto.com/yueliangdao0608/1369057,如需转载请自行联系原作者