Conceitos Fundamentais
As funções de agregação são operadores que consolidam múltiplas linhas em um único valer resumido. Antes dessa consolidação, é possível organizar os dados em grupos específicos e aplicar filtros adicionais sobre esses agrupamentos.
### Funções Básicas de Agregação
Essas funções possuem regras diretas para calcular valores únicos a partir de várias linhas. Os tipos aceitos como parâmetros incluem: tinyint, smallint, int, bigint, decimal, money, smallmoney, float e real.
A Função COUNT()
COUNT() retorna o número total de registros sob determinadas condições.
Para contar todos os funcionários:
SELECT COUNT(*) AS TotalFuncionarios
FROM RecursosHumanos.Funcionario
Quando usado com uma coluna específica, valores NULL não são considerados:
SELECT COUNT(IdGerente) AS FuncionariosComGerente
FROM RecursosHumanos.Funcionario
Utilizando DISTINCT, apenas valores únicos são contabliizados:
SELECT COUNT(DISTINCT IdGerente) AS NumeroDeGerentes
FROM RecursosHumanos.Funcionario
AVG(), SUM(), MAX() e MIN()
Estas funções compartilham sintaxe semelhante e também ignoram valores nulos durante o cálculo.
Média de horas de férias:
SELECT AVG(HorasFerias) AS MediaHorasFerias
FROM RecursosHumanos.Funcionario
Incluindo substituição de valores nulos:
SELECT AVG(ISNULL(HorasFerias, 10)) AS MediaHorasFeriasAjustada
FROM RecursosHumanos.Funcionario
Agrupando Resultados
O comando GROUP BY permite segmentar resultados agregados por categorias específicas.
Total de vendas por território:
SELECT IdTerritorio, SUM(VendasAnoPassado) AS TotalVendas
FROM Vendas.Representante
GROUP BY IdTerritorio
Agrupamento múltiplo por gênero e gerente:
SELECT IdGerente, Genero,
SUM(HorasLicencaMedica) AS HorasLicenca,
COUNT(*) AS NumeroFuncionarios
FROM RecursosHumanos.Funcionario
GROUP BY Genero, IdGerente
A ordem das colunas no GROUP BY afeta a lógica de agrupamento, mas não altera o conjutno final de dados.
Filtragem Pós-Agrupamento
A cláusula HAVING filtra resultados após o agrupamento, diferentemente do WHERE que opera antes da agregação.
Exemplo incorreto usando alias:
-- Este código falha pois HAVING não reconhece aliases
SELECT IdGerente, Genero,
SUM(HorasLicencaMedica) AS HorasLicenca,
COUNT(*) AS NumeroFuncionarios
FROM RecursosHumanos.Funcionario
GROUP BY IdGerente, Genero
HAVING NumeroFuncionarios > 2
Versão correta repetindo a expressão:
SELECT IdGerente, Genero,
SUM(HorasLicencaMedica) AS HorasLicenca,
COUNT(*) AS NumeroFuncionarios
FROM RecursosHumanos.Funcionario
GROUP BY IdGerente, Genero
HAVING COUNT(*) > 2
Expressões Avançadas com HAVING
HAVING permite uso de funções agregadas em suas condições, algo impossível com WHERE.
Selecionando gerentes cujo funcionário com mais licença médica tem ao menos o dobro do mínimo:
SELECT IdGerente,
SUM(HorasLicencaMedica) AS TotalLicenca,
COUNT(*) AS NumeroFuncionarios
FROM RecursosHumanos.Funcionario
GROUP BY IdGerente
HAVING MAX(HorasLicencaMedica) > 2 * MIN(HorasLicencaMedica)
