Essa seção mostra funções de agregação definidas pelo usuário. Os exemplos utilizam os dados da tabela tbl_pessoas mostrada abaixo:
CREATE TABLE tbl_pessoas (
id SERIAL,
nome TEXT,
sobrenome TEXT,
sexo CHAR(1),
altura_cm INT
);
INSERT INTO tbl_pessoas VALUES (DEFAULT,'Ana','Maria','F',175);
INSERT INTO tbl_pessoas VALUES (DEFAULT,'Manoel','Pacheco','M',168);
INSERT INTO tbl_pessoas VALUES (DEFAULT,NULL,'Barbosa',NULL,NULL);
INSERT INTO tbl_pessoas VALUES (DEFAULT,'Doroteia','Braga',NULL,NULL);
INSERT INTO tbl_pessoas VALUES (DEFAULT,'Manoel','Oliveira','M',181);
INSERT INTO tbl_pessoas VALUES (DEFAULT,'Ana','Fraga','F',165);
INSERT INTO tbl_pessoas VALUES (DEFAULT,'Maria','Pereira','F',164);
INSERT INTO tbl_pessoas VALUES (DEFAULT,'Manoel','Silva','M',153);
\pset null '(nulo)'
\pset border 2
\pset title 'Tabela tbl_pessoas'
SELECT * FROM tbl_pessoas;
Tabela tbl_pessoas
+----+----------+-----------+--------+-----------+
| id | nome | sobrenome | sexo | altura_cm |
+----+----------+-----------+--------+-----------+
| 15 | Ana | Maria | F | 175 |
| 16 | Manoel | Pacheco | M | 168 |
| 17 | (nulo) | Barbosa | (nulo) | (nulo) |
| 18 | Doroteia | Braga | (nulo) | (nulo) |
| 19 | Manoel | Oliveira | M | 181 |
| 20 | Ana | Fraga | F | 165 |
| 21 | Maria | Pereira | F | 164 |
| 22 | Manoel | Silva | M | 153 |
+----+----------+-----------+--------+-----------+
(8 linhas)
Essa função de agregação recebe como parâmetro uma cadeia de caracteres, e retorna como resultado essas cadeias de caracteres concatenadas separadas por ponto-e-vírgula.
CREATE OR REPLACE FUNCTION fun_estado_agrega_texto (text[], text)
RETURNS text[] AS $$
SELECT array_append($1, $2);
$$ LANGUAGE SQL STRICT;
CREATE OR REPLACE FUNCTION fun_final_agrega_texto (text[])
RETURNS text AS $$
SELECT array_to_string($1, ';');
$$ LANGUAGE SQL STRICT;
CREATE OR REPLACE AGGREGATE agrega_texto
(
BASETYPE=text,
SFUNC = fun_estado_agrega_texto,
STYPE = text[],
FINALFUNC = fun_final_agrega_texto,
INITCOND = '{}'
);
Nesse exemplo, a função agrega_texto
é utilizada para colocar em uma linha a lista separada por
ponto-e-vírgula de todos os nomes e sobrenomes das pessoas da tabela
tbl_pessoas agrupados por sexo.
\pset null '(nulo)' \pset border 2 \pset title 'Nomes e sobrenomes das pessoas agrupados por sexo' SELECT sexo, agrega_texto(nome || ' ' || sobrenome) AS pessoas FROM tbl_pessoas GROUP BY sexo; Nomes e sobrenomes das pessoas agrupados por sexo +--------+---------------------------------------------+ | sexo | pessoas | +--------+---------------------------------------------+ | (nulo) | Doroteia Braga | | M | Manoel Pacheco;Manoel Oliveira;Manoel Silva | | F | Ana Maria;Ana Fraga;Maria Pereira | +--------+---------------------------------------------+ (3 linhas)
Utilização da função array_accum, definida em
Agregações polimórficas e variádicas, para realizar
a consulta acima permitindo a comparação dos resultados.
\pset title 'Função array_accum (anycompatible)'
SELECT sexo, array_accum(nome || ' ' || sobrenome) AS pessoas
FROM tbl_pessoas
GROUP BY sexo;
Função array_accum (anycompatible)
+--------+-----------------------------------------------------+
| sexo | pessoas |
+--------+-----------------------------------------------------+
| (nulo) | {NULL,"Doroteia Braga"} |
| M | {"Manoel Pacheco","Manoel Oliveira","Manoel Silva"} |
| F | {"Ana Maria","Ana Fraga","Maria Pereira"} |
+--------+-----------------------------------------------------+
(3 linhas)
Essa função de agregação recebe como parâmetro um número inteiro, e retorna como resultado uma cadeias de caracteres com esses números concatenados separados por ponto-e-vírgula.
CREATE OR REPLACE FUNCTION fun_estado_agrega_int(int[], int)
RETURNS int[] AS $$
SELECT array_append($1, $2);
$$ LANGUAGE SQL STRICT;
CREATE OR REPLACE FUNCTION fun_final_agrega_int (int[])
RETURNS text AS $$
SELECT array_to_string($1, ';');
$$ LANGUAGE SQL STRICT;
CREATE OR REPLACE AGGREGATE agrega_int
(
BASETYPE = int,
SFUNC = fun_estado_agrega_int,
STYPE = int[],
FINALFUNC = fun_final_agrega_int,
INITCOND = '{}'
);
Nesse exemplo, a função concat_int
é utilizada para colocar em uma linha a lista separada por
ponto-e-vírgula de todas as alturas das pessoas da tabela
tbl_pessoas agrupadas por sexo.
\pset null '(nulo)' \pset border 2 \pset title 'Função agrega_int()' SELECT sexo, agrega_int(altura_cm) AS alturas FROM tbl_pessoas GROUP BY sexo; Função agrega_int() +--------+-------------+ | sexo | alturas | +--------+-------------+ | (nulo) | | | M | 168;181;153 | | F | 175;165;164 | +--------+-------------+ (3 linhas)
Utilização da função array_accum, definida em
Agregações polimórficas e variádicas, para realizar
a consulta acima permitindo a comparação dos resultados.
\pset title 'Função array_accum (anycompatible)'
SELECT sexo, array_accum(altura_cm) AS alturas
FROM tbl_pessoas
GROUP BY sexo;
Função array_accum (anycompatible)
+--------+---------------+
| sexo | alturas |
+--------+---------------+
| (nulo) | {NULL,NULL} |
| M | {168,181,153} |
| F | {175,165,164} |
+--------+---------------+
(3 linhas)
Essa função de agregação recebe como parâmetro o *,
e retorna como resultado um histograma contendo um *
para cada ocorrência do valor no grupo.
Os valores nulos também são contados.
CREATE OR REPLACE FUNCTION fun_estado_agrega_histograma (text)
RETURNS text AS $$
SELECT $1 || '*';
$$ LANGUAGE SQL STRICT;
CREATE OR REPLACE AGGREGATE agrega_histograma
(
BASETYPE = "ANY",
SFUNC = fun_estado_agrega_histograma,
STYPE = text,
INITCOND = ''
);
Nesse exemplo, a função agrega_histograma
é chamada para criar um histograma das ocorrências dos nomes das
pessoas na tabela tbl_pessoas.
\pset null '(nulo)'
\pset border 2
\pset title 'Histograma dos nomes'
SELECT nome, count(*) AS qtd, agrega_histograma(*) AS histograma
FROM tbl_pessoas
GROUP BY nome
ORDER BY qtd, nome NULLS FIRST;
Histograma dos nomes
+----------+-----+------------+
| nome | qtd | histograma |
+----------+-----+------------+
| (nulo) | 1 | * |
| Doroteia | 1 | * |
| Maria | 1 | * |
| Ana | 2 | ** |
| Manoel | 3 | *** |
+----------+-----+------------+
(5 linhas)