A geração de séries numéricas e temporais tem diversas aplicações em bancos de dados. A produção de uma sequência de inteiros pode ser de grande valia para solucionar vários tipos de problemas, enquanto que uma lista de datas que seja produzida pode permitir o agendamento de tarefas, por exemplo. A função generate_series, implementada pelo postgres, permite a geração de diversas séries sem a necessidade de construção de programas ou funções iterativas, o que economiza esforço de programação.
Exemplos de sequências numéricas.
A função generate_series assume três grandes formas:
- generate_series(valor inicial, valor final) - Gera uma série numérica de valores, partindo do valor inicial ao final, utilizando como incremento o valor 1;
- generate_series(valor inicial, valor final, incremento) - Gera uma série de valores, partindo do valor inicial ao final, utilizando como incremento o valor parametrizado. Produz uma progressão aritmética;
- generate_series(valor inicial, valor final, incremento do tipo intervalar) - Gera uma série temporal de valores, partindo do valor inicial ao final, ambos do tipo timestamp, utilizando como incremento o valor parametrizado.
Abaixo comento algumas das possibilidades oferecidas por estas funções:
* Sequências Simples
Abaixo, sequências numéricas simples que utilizam o incremento 1.
- Sequência simples.
postgres=# SELECT generate_series(1,3);
generate_series
-----------------
1
2
3
(3 registros)
- Sequência simulando incremento de 3 unidades.
postgres=# SELECT generate_series(1,5)*3-2 AS TRIPLO;
triplo
--------
1
4
7
10
13
(5 registros)- Sequência com incremento fracionário.
postgres=# SELECT (generate_series(1,5)*1.0)/2 AS FRACIONARIO;
fracionario
------------------------
0.50000000000000000000
1.00000000000000000000
1.5000000000000000
2.0000000000000000
2.5000000000000000
(5 registros)
- Sequência com valores repetidos, utilizando o operador de resto da divisão.
postgres=# SELECT generate_series(1,10)%5 AS REPETIDO;
repetido
----------
1
2
3
4
0
1 (REPETIÇÕES)
2
3
4
0
(10 registros)
* Sequências Com Incremento Explícito.
- Incremento 1, fornecido.
postgres=# SELECT generate_series(1,5,1);
generate_series
-----------------
1
2
3
4
5
(5 registros)
- Incremento 2, fornecido. Observe que se o valor máximo é atingido, a sequência é interrompida.
postgres=# SELECT generate_series(1,5,2);
generate_series
-----------------
1
3
5
(3 registros)
- Sequência com incremento decrescente.
postgres=# SELECT generate_series(5,1,-1);
generate_series
-----------------
5
4
3
2
1
(5 registros)
* Sequências Temporais.
Exigem um pouco mais de abstração por envolverem intervalos de tempo, mas não são necessariamente complexas. Abaixo elenco alguns exemplos elementares.
- Utilizando timestamps com a sintaxe mais básica.
postgres=# SELECT generate_series('2013-02-06 12:00'::timestamp,
postgres(# '2013-02-08 12:00'::timestamp,
postgres(# '1 day');
generate_series
---------------------
2013-02-06 12:00:00
2013-02-07 12:00:00
2013-02-08 12:00:00
(3 registros)
- Utilizando current_timestamp.
postgres=# SELECT generate_series(current_timestamp,
postgres(# current_timestamp + '5 days',
postgres(# '1 day');
generate_series
-------------------------------
2013-02-06 09:35:31.343344-03
2013-02-07 09:35:31.343344-03
2013-02-08 09:35:31.343344-03
2013-02-09 09:35:31.343344-03
2013-02-10 09:35:31.343344-03
2013-02-11 09:35:31.343344-03
(6 registros)
- Utilizando incremento de algumas horas.
postgres=# SELECT generate_series(current_timestamp,
postgres(# current_timestamp + '1 day',
postgres(# '8 hours');
generate_series
-------------------------------
2013-02-06 09:41:29.799331-03
2013-02-06 17:41:29.799331-03
2013-02-07 01:41:29.799331-03
2013-02-07 09:41:29.799331-03
(4 registros)
- Utilizando incremento decrescente.
postgres=# SELECT generate_series(current_timestamp + '5 days',
postgres(# current_timestamp,
postgres(# '-1 day');
generate_series
-------------------------------
2013-02-11 09:48:26.540137-03
2013-02-10 09:48:26.540137-03
2013-02-09 09:48:26.540137-03
2013-02-08 09:48:26.540137-03
2013-02-07 09:48:26.540137-03
2013-02-06 09:48:26.540137-03
(6 registros)
* Considerações Finais
A função generate_series() permite a economia de tempo e flexibilidade na geração de séries numéricas e temporais, produzindo um resultado legível e de fácil utilização. Não são a única forma de se gerar estes dados no postgres, e afeta a portabilidade de banco de dados, mas é um recurso importante a ser considerado pelos desenvolvedores.