Módulo 3: Agregação
COUNT, SUM, AVG, GROUP BY, HAVING
Teoria
- Funções de agregação resumem várias linhas em uma:
COUNT(x): quantas linhas (ex.: quantos pedidos, quantos casos de teste).SUM(x): soma os valores da coluna (ex.: faturamento total).AVG(x): média dos valores (ex.: ticket médio, tempo médio de execução).MIN(x): o menor valor (ex.: pedido mais barato, data mais antiga).MAX(x): o maior valor (ex.: pedido mais caro, data mais recente).
GROUP BY coluna: calcula a agregação por grupo (ex.: total por status).WHEREfiltra antes de agrupar;HAVINGfiltra depois, sobre o resultado agregado. Ex.:HAVING COUNT(*) > 5.COUNT(*)conta linhas;COUNT(coluna)ignora as linhas em que aquela coluna éNULL.ROUND(x, 2)arredonda, útil pra médias e somas de dinheiro.
Olhar de QA: é assim que se monta métrica: taxa de aprovação por suite, defeitos por módulo, ticket médio por status.
Exemplos de aplicação
Um exemplo montado pra cada item da teoria acima. Não precisa rodar: é pra ver a cara do recurso e entender cada pedaço. Os valores são ilustrativos.
Funções de agregação
SELECT
COUNT(*) AS qtd_pedidos,
SUM(valor_total) AS faturamento,
AVG(valor_total) AS ticket_medio,
MIN(valor_total) AS menor,
MAX(valor_total) AS maior
FROM pedidos
WHERE status <> 'cancelado';
Cada função resume todas as linhas que passaram no WHERE num único número: COUNT(*) quantas linhas, SUM o total, AVG a média, MIN/MAX os extremos. Sem GROUP BY, o resultado é uma linha só.
GROUP BY
SELECT status,
COUNT(*) AS qtd,
SUM(valor_total) AS total
FROM pedidos
GROUP BY status;
GROUP BY status separa os pedidos em pilhas por status e roda a agregação em cada pilha. Resultado: uma linha por status, com a contagem e a soma daquele grupo. Regra: toda coluna que não está numa função de agregação precisa estar no GROUP BY.
WHERE antes, HAVING depois
SELECT cliente_id,
COUNT(*) AS qtd_pedidos
FROM pedidos
WHERE status <> 'cancelado'
GROUP BY cliente_id
HAVING COUNT(*) >= 3;
WHERE corta linhas antes de agrupar (tira os cancelados). HAVING corta depois, olhando o resultado já agregado; aqui mantém só clientes com 3+ pedidos válidos. HAVING pode usar COUNT(*)/SUM(...); WHERE não.
COUNT(*) vs COUNT(coluna)
SELECT
COUNT(*) AS total_execucoes,
COUNT(defeito_id) AS com_defeito_ligado
FROM execucoes_teste;
COUNT(*) conta todas as linhas. COUNT(defeito_id) conta só as linhas em que defeito_id não é NULL. A diferença entre os dois é quantas execuções não têm defeito vinculado.
ROUND(x, 2)
SELECT suite,
ROUND(AVG(duracao_seg), 2) AS duracao_media_seg
FROM execucoes_teste
GROUP BY suite;
AVG(duracao_seg) pode vir com muitas casas (12.83333…). ROUND(x, 2) corta em 2 casas → 12.83. Cosmético, mas essencial em relatório de tempo ou de dinheiro.
Pegadinhas deste módulo
Os erros que quase todo mundo comete aqui. Ler agora poupa meia hora de confusão depois, e alguns deles são a causa de relatório errado em projeto real.
COUNT(*)eCOUNT(coluna)dão respostas diferentes.COUNT(*)conta linhas;COUNT(coluna)ignora as linhas em que aquela coluna éNULL. Usar um pelo outro é a origem de metade dos números errados em relatório de QA.AVGtambém ignoraNULL, e isso muda a média.AVG(duracao)sobre 100 linhas com 40 nulas é a média de 60, não de 100. Se o vazio deveria contar como zero, useAVG(COALESCE(duracao, 0)).WHEREfiltra antes de agrupar;HAVING, depois. Filtrar por valor de linha noHAVINGfunciona em alguns bancos e é lento em todos. E o contrário,WHERE COUNT(*) > 5, simplesmente não existe: agregação não cabe noWHERE.- Grupo sem nenhuma linha não aparece no resultado. Se você agrupa defeitos por módulo, o módulo com zero defeitos não vem na lista: ele some. Quem lê o relatório conclui que o módulo não existe, e não que ele está limpo.
- Cuidado ao somar percentuais já calculados. A média das taxas de falha por suíte não é a taxa de falha geral: suítes com tamanhos diferentes pesam diferente. Some os numeradores e os denominadores, e divida no fim.
Prática
Rode com o botão ou Ctrl+Enter.
carregando banco…