quarta-feira, 6 de fevereiro de 2013

Produza Sequências Com a Função Generate_Series()!

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.

Nenhum comentário: