# PostgreSQL 的 generate_serise 的函数应用
# 简介
PostgreSQL 中有一个很有用处的内置函数 generate_serise,可以按不同的规则产生一系列的填充数据
# 语法
函数 | 参数类型 | 返回类型 | 描述 |
---|
generate_serise(start,stop) | int 或 bigint | setof int 或 setof bigint (与参数类型相同) | 生成一个数值序列,从 start 到 stop,<br /> 步进为 1 |
generate_serise(start,stop,step) | int 或 bigint | setof int 或 setof bigint (与参数类型相同) | 生成一个数值序列,从 start 到 stop,<br /> 步进为 step |
generate_serise(start,stop,step_interval) | timestamp or timestamp with time zone | timestamp 或 timestamp with time zone (same as argument type) | 生成一个数值序列,从 <br />start 到 stop,步进为 step |
# 实例
# int 类型
- 不写步进时默认为 1
| select generate_series(1, 10); |
| |
| generate_series |
| |
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
| 6 |
| 7 |
| 8 |
| 9 |
| 10 |
| (10 rows) |
- 设置步进
| select generate_series(1, 10, 3); |
| |
| generate_series |
| |
| 1 |
| 4 |
| 7 |
| 10 |
| (4 rows) |
- 如果 step 是正数,而 start 大于 stop,那么返回零行。相反,如果 step 是负数,start 小于 stop,则返回零行。如果是 NULL 输入,也产生零行。step 为零则是一个错误
| select generate_series(5,1); |
| |
| generate_series |
| |
| (0 rows) |
NULL inputs
| select generate_series(5,null); |
| |
| generate_series |
| |
| (0 rows) |
step 为零
| select generate_series(5,1,0); |
| ERROR: step size cannot equal zero |
start 大于 stop,step 是负数
| select generate_series(5,1,-1); |
| |
| generate_series |
| |
| 5 |
| 4 |
| 3 |
| 2 |
| 1 |
| (5 rows) |
时间类型
| select generate_series(now(), now() + '7 days', '1 day'); |
| |
| generate_series |
| |
| 2013-04-03 14:22:26.391852+08 |
| 2013-04-04 14:22:26.391852+08 |
| 2013-04-05 14:22:26.391852+08 |
| 2013-04-06 14:22:26.391852+08 |
| 2013-04-07 14:22:26.391852+08 |
| 2013-04-08 14:22:26.391852+08 |
| 2013-04-09 14:22:26.391852+08 |
| 2013-04-10 14:22:26.391852+08 |
| (8 rows) |
| select generate_series(to_date('20130403','yyyymmdd'), to_date('20130404','yyyymmdd'), '3 hours'); |
| |
| generate_series |
| |
| 2013-04-03 00:00:00+08 |
| 2013-04-03 03:00:00+08 |
| 2013-04-03 06:00:00+08 |
| 2013-04-03 09:00:00+08 |
| 2013-04-03 12:00:00+08 |
| 2013-04-03 15:00:00+08 |
| 2013-04-03 18:00:00+08 |
| 2013-04-03 21:00:00+08 |
| 2013-04-04 00:00:00+08 |
| (9 rows) |
# IP 类型
- 建表
| create table tbl_david(id int, ip_start inet, ip_stop inet); |
- 插入数据
| insert into tbl_david values (1, '192.168.1.6', '192.168.1.10'); |
| insert into tbl_david values (2, '192.168.2.16', '192.168.2.20'); |
| insert into tbl_david values (3, '192.168.3.116', '192.168.3.120'); |
- 查询数据
| select * from tbl_david ; |
| |
| id | ip_start | ip_stop |
| |
| 1 | 192.168.1.6 | 192.168.1.10 |
| 2 | 192.168.2.16 | 192.168.2.20 |
| 3 | 192.168.3.116 | 192.168.3.120 |
| (3 rows) |
- generate_serise 生成序列
| select id, generate_series(0, ip_stop-ip_start)+ip_start as ip_new from tbl_david; |
| |
| id | ip_new |
| |
| 1 | 192.168.1.6 |
| 1 | 192.168.1.7 |
| 1 | 192.168.1.8 |
| 1 | 192.168.1.9 |
| 1 | 192.168.1.10 |
| 2 | 192.168.2.16 |
| 2 | 192.168.2.17 |
| 2 | 192.168.2.18 |
| 2 | 192.168.2.19 |
| 2 | 192.168.2.20 |
| 3 | 192.168.3.116 |
| 3 | 192.168.3.117 |
| 3 | 192.168.3.118 |
| 3 | 192.168.3.119 |
| 3 | 192.168.3.120 |
| (15 rows) |
搞不懂这是为什么我们可以进行拆解
| |
| SELECT (ip_stop - ip_start)+ip_start as ip_new FROM tbl_david |
| |
| ip_new |
| |
| 192.168.1.10 |
| 192.168.2.20 |
| 192.168.3.120 |
| (3 rows) |
| |
| select id, generate_series(0, 4)+ip_start as ip_new from tbl_david; |
| |
| id | ip_new |
| |
| 1 | 192.168.1.6 |
| 1 | 192.168.1.7 |
| 1 | 192.168.1.8 |
| 1 | 192.168.1.9 |
| 1 | 192.168.1.10 |
| 2 | 192.168.2.16 |
| 2 | 192.168.2.17 |
| 2 | 192.168.2.18 |
| 2 | 192.168.2.19 |
| 2 | 192.168.2.20 |
| 3 | 192.168.3.116 |
| 3 | 192.168.3.117 |
| 3 | 192.168.3.118 |
| 3 | 192.168.3.119 |
| 3 | 192.168.3.120 |
| (15 rows) |
# 总结
PostgreSQL 的 generate_serise 函数对生成测试数据,批量更新一定规则的数据有比较多的应用场景,使用得当可提升发开效率,另外 IP 的序列生成也是 PG 的一个亮点