Trabalhando com as funções de agregação do SQL

O SQLStructured Query Language (Linguagem de Consulta Estruturada) é uma linguagem usada para dar manutenção nos dados em um bancos de dados. Oracle, Sybase e MS SQL Server são alguns exemplos de servidores de bancos de dados que se valem dessa linguagem tanto para permitir a extração dos dados armazenados como para inserir novos dados ou atualizar aqueles já existentes. A primeira versão da sintaxe foi padronizada em 1986 e a última revisão foi aprovada pelo ISO em 2008.

Desde a primeira versão, o padrão incorpora funções classificadas como “agregação”. São funções nativas de consulta que servem para agrupar informações, agregando numa única linha o conteúdo de vários registros. Dessa forma, os detalhes da informação original são postos de lado e as informações são tratadas em conjunto.

Atualmente, as funções de agregação disponíveis no SQL são as seguintes: AVG (calcula a média dos valores de um campo determinado), COUNT (retorna a quantidade de registros existentes), SUM (calcula a soma dos valores de um determinado campo), MAX (retorna o maior valor existente para um campo especificado) e MIN (retorna o menor valor existente para um campo especificado). Todas essas funções são aplicadas apenas aos registros que atenderem os critérios estabelecidos na cláusula WHERE da query onde estiverem sendo usadas.

Pode parecer confuso a princípio mas o conceito de agregação é, na verdade, bastante simples. Considere o seguinte conjunto de registros existente numa tabela no banco de dados:

NF Produto Cliente Qtde Valor Dia
1 P001 C1 8 R$ 160,00 5
1 P002 C1 2 R$ 34,00 5
1 P003 C1 1 R$ 58,00 5
2 P002 C3 20 R$ 340,00 7
3 P001 C2 12 R$ 240,00 8
3 P002 C2 5 R$ 85,00 8
4 P001 C1 2 R$ 40,00 10
5 P003 C3 4 R$ 232,00 15


Um exemplo simples de agregação com esses registros seria somar a coluna Valor deles todos. Supondo que a tabela se chame TABELA, a query e seu retorno seriam:

SELECT SUM (Valor) FROM TABELA


——————
1189,00

Repare que apenas um registro é retornado. É por isso que eu disse que as agregações escondem os detalhes dos registros envolvidos. O uso de agregações não impede que se aplique a cláusula WHERE na query, isto é, ainda posso restringir quais registros eu quero incluir na agregação. O exemplo da soma considerando apenas as notas do cliente C1 ficaria:

SELECT SUM (Valor) FROM TABELA
WHERE Cliente = ‘C1’


——————
292,00

Na maioria dos casos, restringir tanto os registros afetados e o retorno não é desejável. Numa aplicação real, quase sempre as informações terão que vir um pouco mais detalhadas. Pode ser necessário, por exemplo, trazer as somas de cada cliente separadamente, sem que se tenha que especificar um cliente em particular. Esse efeito é obtido agrupando-se os registros através da cláusula GROUP BY.

SELECT Cliente, SUM (Valor), COUNT(*) AS QtdeReg
FROM TABELA
GROUP BY Cliente


Cliente QtdeReg
—————— —————— ——————
C1 292,00 4
C2 325,00 2
C3 572,00 2

Acrescentei no quadro anterior também uma coluna que mostra quantos registros da tabela foram considerados em cada linha trazida, isto é, quantos registros estão agregados em cada linha. Isso exemplifica o uso da função COUNT.

Se for preciso, é permitido detalhar ainda mais as informações adicionando novos agrupamentos – o produto ou o dia da movimentação, por exemplo. Além disso, todos os elementos de uma query comum podem ser usados, tais como o WHERE (já mostrado) e o ORDER BY (para que as linhas retornadas estejam classificadas numa determinada ordem).

A cláusula WHERE determina quais os registros da tabela devem ser incluídos na agregação. E se você quiser restringir as linhas retornadas, trazendo apenas aquelas que atingirem determinado valor agregado ? Suponha, por exemplo, que na query do quadro anterior você queria exibir apenas os clientes cuja soma de valor seja superior a 300 ? Para esta situação, o padrão SQL define a cláusula HAVING que nada mais é que um WHERE aplicado ao resultado da agregação. Veja a implementação do exemplo:

SELECT Cliente, SUM (Valor), COUNT(*) AS QtdeReg
FROM TABELA
GROUP BY Cliente
HAVING (SUM (Valor) > 300) AND (COUNT(*) >= 1)


Cliente QtdeReg
—————— —————— ——————
C2 325,00 2
C3 572,00 2

Repare que o HAVING é aplicado após o agrupamento (GROUP BY) enquanto o WHERE é aplicado ao SELECT. O exemplo também mostra que é possível combinar mais de um valor de agregação no HAVING para obter filtros mais complexos.

Fonte: Balaio Tecnológico

Luís Gustavo Fabbro

Mais artigos deste autor »

Bacharel em Ciências da Computação, formado pela Unesp Bauru. Foi responsável pelos módulos da área industrial do ERP da ABC71 Soluções em Informática entre 1993 e 1998. Em 2002, passou a ser responsável pela então nascente área de Pesquisa & Desenvolvimento da empresa. É profissional certificado pela Microsoft, com especialização na arquitetura do Sistema Operacional Windows e mantem o blog Balaio Tecnológico, dedicado a tecnologia.


Deixe seu comentário

Seu endereço de e-mail não será publicado. Campos com * são obrigatórios!