Olá,
Em 29 de outubro de 2010 10:15, Emerson Hermann
<[email protected]>escreveu:
> /*
> 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
>
De uma olhada no blog do Fábio Telles [1], ele postou lá esta semana um
exemplo do uso de Window Functions.
> 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
>
[1] http://www.midstorm.org/~telles/
[]s
--
JotaComm
http://jotacomm.wordpress.com
_______________________________________________
pgbr-geral mailing list
[email protected]
https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral