terça-feira, 8 de dezembro de 2009

Relatórios sobre logs no Oracle

É tão comum usar count() em selects, que é fácil esquecer como o sum() pode ser útil também. Frequentemente, por exemplo, preciso fazer relatórios sobre tabelas de log, totalizando as diferentes ações registradas.

Suponha, por exemplo, que eu tenha uma tabela que registre uploads e downloads de arquivos, por usuários. Esta tabela poderia ter as seguintes colunhas:

  1. Nome do usuário;
  2. Data da ação,
  3. Tipo da ação (upload ou download).
O relatório que eu quero precisa mostrar, em cada linha:

  1. O nome do usuário;
  2. O total de registros;
  3. O total de uploads;
  4. O total de downloads.
O problema está, obviamente, em que count() não vai permitir que eu separe por colunas dados que estão dispostos em linhas. Mas sum(), com um pouco de ajuda do case, permite resolver esse problema.


select usuario,
count(1) total,
sum(case when acao='Upload' then 1 else 0 end) uploads,
sum(case when acao='Download' then 1 else 0 end) downloads
from historico
group by usuario
order by 2 desc

Então, para cada linha, cada sum() vai somar 1 ou 0, conforme o valor da coluna acao. O count(1) vai contar o número de linhas agrupadas por usuário e será sempre igual a soma de uploads e downloads, a menos que haja mais tipos de ações.

Nenhum comentário: