9.26. Funções que retornam conjunto #

Esta seção descreve funções que possivelmente retornam mais de uma linha. As funções mais utilizadas nesta classe são as funções geradoras de séries, conforme detalhado na Tabela 9.69 e na Tabela 9.70. Outras funções que retornam conjunto mais especializadas estão descritas em outras partes deste manual. Veja a Seção 7.2.1.4 para conhecer maneiras de combinar várias funções que retornam conjunto.

Tabela 9.69. Funções geradoras de séries

Função

Descrição

generate_series ( start integer, stop integer [, step integer ] ) → setof integer

generate_series ( start bigint, stop bigint [, step bigint ] ) → setof bigint

generate_series ( start numeric, stop numeric [, step numeric ] ) → setof numeric

Gera uma série de valores desde start até stop, com o tamanho do passo igual a step. O valor padrão de step é 1.

generate_series ( start timestamp, stop timestamp, step interval ) → setof timestamp

generate_series ( start timestamp with time zone, stop timestamp with time zone, step interval [, timezone text ] ) → conjunto de carimbos de data e hora com zona horária

Gera uma série de valores desde start até stop, com o tamanho do passo igual a step. No formato que leva em consideração a zona horária, as horas do dia e os ajustes de horário de verão são calculados de acordo com a zona horária especificada pelo argumento timezone, ou pela configuração corrente de TimeZone caso este argumento seja omitido.


Quando step for positivo, serão retornadas zero linhas se start for maior que stop. Inversamente, quando step for negativo serão retornadas zero linhas se start for menor que stop. Também serão retornadas zero linhas se qualquer entrada for NULL. É um erro step ser zero. Seguem alguns exemplos:

SELECT * FROM generate_series(2,4);

 generate_series
-----------------
               2
               3
               4
(3 linhas)

SELECT * FROM generate_series(5,1,-2);

 generate_series
-----------------
               5
               3
               1
(3 linhas)

SELECT * FROM generate_series(4,3);

 generate_series
-----------------
(0 linha)

SELECT generate_series(1.1, 4, 1.3);

 generate_series
-----------------
             1.1
             2.4
             3.7
(3 linhas)

-- este exemplo utiliza o operador de data mais número inteiro:
SELECT current_date + s.a AS dates FROM generate_series(0,14,7) AS s(a);

   dates
------------
 2026-02-02
 2026-02-09
 2026-02-16
(3 linhas)

SELECT * FROM generate_series('2008-03-01 00:00'::timestamp,
                              '2008-03-04 12:00', '10 hours');

   generate_series
---------------------
 2008-03-01 00:00:00
 2008-03-01 10:00:00
 2008-03-01 20:00:00
 2008-03-02 06:00:00
 2008-03-02 16:00:00
 2008-03-03 02:00:00
 2008-03-03 12:00:00
 2008-03-03 22:00:00
 2008-03-04 08:00:00
(9 linhas)

-- este exemplo pressupõe que a zona horária esteja definida como UTC;
-- observe a transição para o horário de verão:
SELECT * FROM generate_series('2001-10-22 00:00 -04:00'::timestamptz,
                              '2001-11-01 00:00 -05:00'::timestamptz,
                              '1 day'::interval, 'America/New_York');

    generate_series
------------------------
 2001-10-22 04:00:00+00
 2001-10-23 04:00:00+00
 2001-10-24 04:00:00+00
 2001-10-25 04:00:00+00
 2001-10-26 04:00:00+00
 2001-10-27 04:00:00+00
 2001-10-28 04:00:00+00
 2001-10-29 05:00:00+00
 2001-10-30 05:00:00+00
 2001-10-31 05:00:00+00
 2001-11-01 05:00:00+00
(11 linhas)

Tabela 9.70. Funções geradoras de índice

Função

Descrição

generate_subscripts ( array anyarray, dim integer ) → setof integer

Gera uma série contendo os índices válidos da dim-ésima dimensão da matriz fornecida.

generate_subscripts ( array anyarray, dim integer, reverse boolean ) → setof integer

Gera uma série contendo os índices válidos da dim-ésima dimensão da matriz fornecida. Quando reverse for verdade, retorna a série na ordem inversa.


generate_subscripts é uma função de conveniência que gera o conjunto de índices válidos para a dimensão especificada da matriz fornecida. São retornadas zero linhas para as matrizes que não possuem a dimensão especificada, ou se alguma entrada for NULL. Seguem alguns exemplos:

-- uso básico:
SELECT generate_subscripts('{NULL,1,NULL,2}'::int[], 1) AS s;

 s
---
 1
 2
 3
 4
(4 linhas)

-- na presença de uma matriz, obter o índice e o valor indexado
-- requer uma subconsulta:
SELECT * FROM arrays;

         a
--------------------
 {-1,-2}
 {100,200,300}
(2 linhas)

SELECT a AS array, s AS subscript, a[s] AS value
FROM (SELECT generate_subscripts(a, 1) AS s, a FROM arrays) foo;

     array     | subscript | value
---------------+-----------+-------
 {-1,-2}       |         1 |    -1
 {-1,-2}       |         2 |    -2
 {100,200,300} |         1 |   100
 {100,200,300} |         2 |   200
 {100,200,300} |         3 |   300
(5 linhas)

-- Linhas da matriz de Hankel (exemplo do tradutor)
-- veja exemplo em '9.19. Funções e operadores para matrizes'
SELECT hankel, s AS linha, hankel[s:s] AS valor
FROM (SELECT generate_subscripts(hankel, 1) AS s, hankel FROM hankel(3,4)) foo;

             hankel              | linha |    valor
---------------------------------+-------+-------------
 {{1,2,3,4},{2,3,4,5},{3,4,5,6}} |     1 | {{1,2,3,4}}
 {{1,2,3,4},{2,3,4,5},{3,4,5,6}} |     2 | {{2,3,4,5}}
 {{1,2,3,4},{2,3,4,5},{3,4,5,6}} |     3 | {{3,4,5,6}}
(3 linhas)

-- desaninhar (unnest) uma matriz 2D:
CREATE OR REPLACE FUNCTION unnest2(anyarray)
RETURNS SETOF anyelement AS $$
select $1[i][j]
   from generate_subscripts($1,1) g1(i),
        generate_subscripts($1,2) g2(j);
$$ LANGUAGE sql IMMUTABLE;
SELECT * FROM unnest2(ARRAY[[1,2],[3,4]]);

 unnest2
---------
       1
       2
       3
       4
(4 linhas)

Quando a função na cláusula FROM recebe o sufixo WITH ORDINALITY, é anexada uma coluna bigint à(s) coluna(s) de saída da função, começando p or 1 e incrementado por 1 para cada linha de saída da função. Isto é mais útil no caso de funções que retornam conjunto, como unnest().

-- função que retorna conjunto com WITH ORDINALITY:
-- execute antes 'sudo su postgres', 'cd ~' e 'psql'
SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n);

          ls          | n
----------------------+----
 pg_stat_tmp          |  1
 pg_serial            |  2
 pg_notify            |  3
 base                 |  4
 pg_subtrans          |  5
 postmaster.pid       |  6
 pg_xact              |  7
 pg_commit_ts         |  8
 pg_stat              |  9
 pg_dynshmem          | 10
 pg_snapshots         | 11
 PG_VERSION           | 12
 pg_logical           | 13
 postmaster.opts      | 14
 pg_multixact         | 15
 pg_twophase          | 16
 global               | 17
 pg_tblspc            | 18
 postgresql.auto.conf | 19
 pg_replslot          | 20
 pg_wal               | 21
(21 linhas)