Sunteți pe pagina 1din 4

Funes Analticas em Oracle parte 2

Na primeira parte deste artigo, resolvemos um problema usual que exigiu a


utilizao da clusula OVER para podermos calcular uma funo de grupo que
extraiu informao em um agrupamento de dados.
Neste artigo vamos explorar um pouco mais o que pode ser feito com esta
partcula. A primeira coisa que pode-se extrair mais particionamentos em um
nico comando SELECT. Para isto basta utilizar quantas clusulas OVER forem
necessrias. Veja um exemplo:
Seu diretor adorou a qualidade a soluo que voc apresentou, mas, como ele
notou que pode extrair mais informaes do banco de dados, ele tambm gostaria
de ver o maior valor de prestao da empresa. Desta forma, alm de voc mostrar
o maior valor de prestao a cada ms e o respectivo contrato, ele tambm quer
saber qual o maior valor de prestao de toda empresa.
Para resolver este problema, voc ter que repetir o comando anterior e
acrescentar uma nova coluna com o novo particionamento da busca. Neste caso,
voc ainda utilizar a funo de grupo MAX, mas utilizar a clusula OVER atuando
na coluna CDEMPRESA. Veja como fica o comando:
SELECT dtvenc, cdempresa, cdcontr, vlprest, max_empresa
FROM (
SELECT to_char( dtvenc, 'MM-YYYY') dtvenc,
cdcontr, vlprest,
MAX( vlprest ) OVER
(PARTITION BY to_char(dtvenc,'YYYYMM')) max_prest,
MAX( vlprest ) OVER
(PARTITION BY cdempresa ) max_empresa
FROM vRECEBER
WHERE dtvenc > sysdate ) WHERE vlprest = max_prest;
O resultado da busca est na figura 1:

Figura 1: resultado do comando com duas clusulas OVER


Isto foi muito fcil... Agora o diretor gostaria de uma nova informao: quais so as
3 maiores prestaes de cada ms e os respectivos contratos?
Bem, agora no temos apenas uma funo de grupo envolvida. Precisamos
estabelecer uma ordem no valor das prestaes e selecionar somente as 3 maiores.
Isso o que se chama de Ranking. A clusula que utilizaremos para resolver este
problema tambm tem o mesmo nome: RANK. A utilizao bastante simples.
Uma vez que sabemos utilizar o OVER j estamos com quase tudo resolvido. Vamos
simplesmente indicar que faremos um particionamento dos valores de prestao
por data (exatamente como fizemos anteriormente), mas vamos indicar que
queremos o resultado em uma determinada ordem (ORDER BY). Para indicar ao
Oracle que queremos estabelecer um ranking dos resultados, vamos acrescentar a
clusula RANK antes do OVER. Assim:

SELECT dtvenc, cdcontr, prestacao, rank


FROM (
SELECT to_char( dtvenc,'MM-YYYY' ) dtvenc, cdcontr,
vlprest prestacao,
RANK() OVER (
PARTITION BY to_char( dtvenc,'YYYYMM' )
ORDER BY vlprest DESC ) rank
FROM vreceber
WHERE DTVENC > SYSDATE )
WHERE rank <= 3
ORDER BY rank DESC;
Nada muito complicado. Tivemos que utilizar uma tabela virtual criada na clusula
FROM do primeiro comando SELECT para facilitar a localizao e exposio dos
dados. Note que isso foi feito apenas para facilitar a seleo (filtro) das 3 maiores
prestaes (clusula WHERE do primeiro SELECT). Como atribumos o nome
RANK para a coluna criada a partir do RANK OVER, o filtro tornou-se possvel. O
RANK OVER e o particionamento da busca foi criado da mesma forma que
anteriormente. Cada linha do SELECT aninhado recebe uma numerao que indica a
seqncia (ou posio) que ela ocupa na pesquisa. Note que o ORDER BY deste
mesmo SELECT indica que se quer em ordem decrescente, ou seja, do maior para o
menor. No foi colocar um argumento em RANK porque a funo simplesmente
indicar a ordem de classificao do ranking.
O resultado da busca est na figura 2:

Figura 2: resultado do ranking.

Uso de Funes Analticas no Oracle Parte 2

Introduo
Na primeira parte deste artigo, publicado na edio anterior, as funes analticas,
utilizadas para facilitar as anlises de negcios (Business Inteligence) e dar suporte
a tarefas analticas para apoio deciso, tiveram seus conceitos gerais
apresentados.
As funes referentes classificao e cruzamento de informaes sero
apresentadas com detalhes nesta edio, merecendo ateno especial.
Funes Analticas de Classificao
As funes analticas de classificao so uma forma fcil de calcular a posio de
cada registro em relao aos demais. Os registros podem ser classificados com
base no valor (crescente ou decrescente) de uma determinada coluna ou com base
em distribuio e percentis, como veremos no decorrer das funes apresentadas
nesta seo.
RANK e DENSE_RANK
As funes RANK e DENSE_RANK classificam resultados de uma seleo com base
em uma das colunas selecionadas (em ordem crescente (ASC) ou decrescente
(DESC)) na clusula ORDER BY, que obrigatria. Os valores classificados ainda
podem estar particionados em grupos atravs da clusula PARTITION BY. Neste
caso, a classificao recomear do valor 1 cada vez que o valor do conjunto de
colunas da clusula PARTITION BY se alterar. A Listagem 1 apresenta a definio
dos comandos de classificao.
RANK ou DENSE_RANK ( )
OVER ([PARTITION BY lista de itens para partio]
[ORDER BY lista de itens que ordenam a classificao] [ASC ou DESC]
[NULLS FIRST ou NULLS LAST])
Listagem 1 Sintaxe dos comandos de classificao.
O exemplo da Listagem 2 classifica as cidades por quantidade de clientes aos
finais de semana usando a funo analtica de classificao RANK no particionada.
select RPAD(s.city,20) "Cidade",
SUM(f.customer_count) "Cliente",
RANK() OVER(ORDER BY SUM(f.customer_count) DESC) "Colocao"
from times t, store s, sales_fact f
where t.time_key = f.time_key and
s.store_key = f.store_key and
t.day_of_week in ('Sunday', 'Saturday')
GROUP BY s.city
ORDER BY 3;
Cidade
Cliente Colocao
----------- ---------- -------------New York
22722
1
Cincinnati
11443
2
Louisville
10731
3
...
Dallas
2276
20
Listagem 2 Utilizao de Funo analtica RANK no particionada

O exemplo da Listagem 3 classifica as cidades por quantidade de clientes aos


Sbados e Domingos. Para isto, faz uso da funo analtica de classificao RANK
particionada, onde a partio acontece por dia da semana, gerando assim uma
classificao para o Sbado e outra para o Domingo.
select t.day_of_week "Dia Semana",
RPAD(s.city,20) "Cidade",
SUM(f.customer_count) "Cliente",
RANK() OVER(PARTITION BY t.day_of_week ORDER BY
SUM(f.customer_count) DESC) Colocao"
from times t, store s, sales_fact f
where t.time_key = f.time_key and
s.store_key = f.store_key and
t.day_of_week in (Sunday, Saturday)
GROUP BY t.day_of_week, s.city
ORDER BY 1, 4;
Dia Semana Cidade
Cliente Colocao
----------- ---------- ------- --------Saturday ">

S-ar putea să vă placă și