Tuesday, January 10, 2006
PIVOT
Uma técnica comum em SQL é o Pivot. Algumas vezes temos necessidade de apresentar relatórios por grupo, por exemplo o cliente possui alguns telefones de contato, mas eles estão em registros diferentes ao longo da tabela, por que no desenho, cada registro do telefone mostra se o número é residência, celular ou comercial (tipo 1, 2 ou 3).
Exemplo!
Primeiro os dados - T é a tabela onde estão os telefones, nm_tel número e tipo_fone classificação em residência, celular ou comercial.
Como podemos notar, temos 4 clientes diferentes e, em nosso exemplo o número de telefones diferentes por cliente é razoável para fazermos um pivot em sql puro, em outra oportunidade, mostrarei um pivot genérico usando pl/sql.
De volta ao exemplo, para saber quantas colunas devemos distribuir os números de telefone por cliente, pegamos o maior valor da quantidade de telefones por cliente.
3 (três), portanto. Com essa informação, montamos nosso pivot para apresentar o cliente e seus respectivos telefones - tudo em uma linho só. O uso do max() é um truque para que seu result set não vire uma "escada" (para ver o efeito escada, basta retirar o max da query).
Exemplo!
Primeiro os dados - T é a tabela onde estão os telefones, nm_tel número e tipo_fone classificação em residência, celular ou comercial.
SQL> select * from t;
COD_CLIENTE NM_TEL TIPO_FONE
------------- ------------- -------------
5 50832590 1
5 55727019 2
6 62856486 1
6 97465225 2
6 36676744 2
7 65214314 1
7 99042269 1
8 69528914 3
8 91252514 1
9 rows selected.
Como podemos notar, temos 4 clientes diferentes e, em nosso exemplo o número de telefones diferentes por cliente é razoável para fazermos um pivot em sql puro, em outra oportunidade, mostrarei um pivot genérico usando pl/sql.
De volta ao exemplo, para saber quantas colunas devemos distribuir os números de telefone por cliente, pegamos o maior valor da quantidade de telefones por cliente.
SQL>
SQL> select max(cnt)
2 from ( select cod_cliente, count(*) cnt
3 from t
4 group by cod_cliente )
5 /
MAX(CNT)
-------------
3
1 row selected.
3 (três), portanto. Com essa informação, montamos nosso pivot para apresentar o cliente e seus respectivos telefones - tudo em uma linho só. O uso do max() é um truque para que seu result set não vire uma "escada" (para ver o efeito escada, basta retirar o max da query).
SQL>
SQL> select cod_cliente,
2 max(decode(rn, 1, nm_tel, null)) nm_tel1,
3 max(decode(rn, 2, nm_tel, null)) nm_tel2,
4 max(decode(rn, 3, nm_tel, null)) nm_tel3
5 from (
6 select cod_cliente, nm_tel,
7 row_number() over (partition by cod_cliente
8 order by cod_cliente ) rn
9 from t
10 )
11 group by cod_cliente
12 /
COD_CLIENTE NM_TEL1 NM_TEL2 NM_TEL3
------------- ------------- ------------- -------------
5 55727019 50832590
6 97465225 62856486 36676744
7 65214314 99042269
8 69528914 91252514
4 rows selected.
Labels: how to
Comments:
<< Home
Vou escrever um artigo exclusivp para tratar disso, basicamente seria um função em pl/sql que receberá como argumento a query e devolverá um refcursor com as colunas.
Post a Comment
<< Home