/*
Obrigado Osvaldo e JotaComm, ufa! como simplificou a minha vida, vejam
como fazia antes com store function e de longe não era melhor solução
comparada com esta, desde já agradeço se alguém quiser postar algum
exemplo com window function
Veja como fazia com store function, como era sofrivel a minha vida :)
*/
--type do store function
DROP TYPE IF EXISTS public.tp_transform_rows_into_column CASCADE;
CREATE TYPE public.tp_transform_rows_into_column AS
(
c1 TEXT
, c2 TEXT
, c3 TEXT
, c4 TEXT
);
--store function
DROP FUNCTION IF EXISTS sf_transform_rows_into_column (sqlx TEXT);
CREATE OR REPLACE FUNCTION sf_transform_rows_into_column (sqlx TEXT)
RETURNS SETOF public.tp_transform_rows_into_column AS
$$
DECLARE
row1 public.tp_transform_rows_into_column;
row2 public.tp_transform_rows_into_column;
row3 public.tp_transform_rows_into_column;
ds_comando TEXT;
controle TEXT;
n_col_transf_rx TEXT;
n_contador FLOAT;
BEGIN
IF (sqlx IS NULL) THEN
RAISE EXCEPTION 'QUERY VALORES NULOS!'; -- caso o parametro venha nulo
END IF;
n_col_transf_rx := '';
ds_comando := 'SELECT * FROM ( ' || sqlx || ' ) AS foo
ORDER BY 1 ASC, 3 ASC';
controle := '';
n_contador := 0;
FOR row1 IN EXECUTE
ds_comando
LOOP
IF row1.c1 <> controle THEN
n_col_transf_rx := '';
row2.c1 := row1.c1;
row2.c2 := row1.c2;
row2.c3 := row1.c3;
row2.c4 := row1.c4 || ';';
n_col_transf_rx := row1.c4 || ';';
ELSIF row1.c1 = controle THEN
n_col_transf_rx := n_col_transf_rx || row1.c4 ||
';';
row2.c4 := n_col_transf_rx;
END IF;
IF row2.c1 <> row3.c1 THEN
RETURN NEXT row3;
END IF;
controle := row1.c1;
row3 := row2;
n_contador := n_contador + 1;
RAISE NOTICE 'Processando tupla... %', n_contador;
END LOOP;
RETURN NEXT row2;
RAISE NOTICE 'Processo concluido com sucesso!!!';
RETURN;
EXCEPTION WHEN QUERY_CANCELED THEN
RAISE NOTICE 'Processo cancelado, ROLLBACK EFETUADO!!!';
RETURN;
END;
$$
LANGUAGE 'plpgsql'
;
-- depois para execução
--como havia anteriormente feito
SELECT *
FROM sf_transform_rows_into_column
($$
SELECT cpf
, nome
, 1 AS status
, matricula
FROM cadastro_teste ORDER BY cpf
$$);
-- com a versão sugerida por Osvaldo na versão PostgreSQL 8.3, ficou assim:
-- para versao Postgres 8.3
CREATE AGGREGATE array_accum (anyelement)
(
sfunc = array_append,
stype = anyarray,
initcond = '{}'
);
SELECT cpf, nome, array_accum(matricula) FROM cadastro_teste GROUP BY
cpf, nome; -- apenas na versao do Postgres 8.3
--Muito simples ! Show!
--Valeu !
/*
Emerson Hermann
DBA
*/
Em 29 de outubro de 2010 08:58, JotaComm <[email protected]> escreveu:
> Opa,
>
> 2010/10/28 Emerson Hermann <[email protected]>
>>
>> /*
>> Estrutura apenas para exemplo
>> */
>> --DROP TABLE IF EXISTS cadastro_teste;
>> CREATE TEMP TABLE cadastro_teste
>> (
>> cpf VARCHAR(11)
>> , nome VARCHAR(21)
>> , matricula VARCHAR(7)
>>
>> );
>>
>> INSERT INTO cadastro_teste (nome,cpf,matricula) VALUES ('Maria
>> Madalena','72034054401','2010011');
>> INSERT INTO cadastro_teste (nome,cpf,matricula) VALUES
>> ('Jonas','12034054408','2010032');
>> INSERT INTO cadastro_teste (nome,cpf,matricula) VALUES ('Maria
>> Madalena','72034054401','2010051');
>> INSERT INTO cadastro_teste (nome,cpf,matricula) VALUES ('Maria
>> Madalena','72034054401','2010071');
>> INSERT INTO cadastro_teste (nome,cpf,matricula) VALUES
>> ('Jonas','12034054408','2010559');
>> INSERT INTO cadastro_teste (nome,cpf,matricula) VALUES
>> ('Marcos','42034054403','2010033');
>> INSERT INTO cadastro_teste (nome,cpf,matricula) VALUES
>> ('Marcos','42034054403','2010154');
>> INSERT INTO cadastro_teste (nome,cpf,matricula) VALUES
>> ('Joao','53034054403','2010004');
>>
>>
>> SELECT * FROM cadastro_teste ORDER BY cpf;
>> /*
>>
>> cpf |nome |matricula
>> 12034054408|Jonas |2010559
>> 12034054408|Jonas |2010032
>> 42034054403|Marcos |2010154
>> 42034054403|Marcos |2010033
>> 53034054403|Joao |2010004
>> 72034054401|Maria Madalena|2010071
>> 72034054401|Maria Madalena|2010051
>> 72034054401|Maria Madalena|2010011
>>
>> */
>>
>> -- Existe a possibilidade de agrupar esses dados da forma abaixo
>> (concatenando a matricula) sem uso de store function? Utilizo
>> PostgreSQL 8.3.
>> -- Se existe, como seria, com window function ?
>
> Sim, com o uso de Window Functions, porém disponível apenas para a versão
> 8.4
>>
>>
>> /*
>> cpf |nome |matricula
>> 12034054408|Jonas |2010032;2010559;
>> 42034054403|Marcos |2010033;2010154;
>> 53034054403|Joao |2010004;
>> 72034054401|Maria Madalena|2010011;2010051;2010071;
>> */
>
> O restante o meu colega Osvaldo já deu a dica.
>>
>> _______________________________________________
>> pgbr-geral mailing list
>> [email protected]
>> https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral
>
>
> []s
> --
> JotaComm
> http://jotacomm.wordpress.com
>
> _______________________________________________
> pgbr-geral mailing list
> [email protected]
> https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral
>
>
_______________________________________________
pgbr-geral mailing list
[email protected]
https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral