Como contar e somar por grupo no SQL?
COUNT e SUM são funções de agregação: em vez de devolver uma linha por linha da tabela, elas devolvem uma conta sobre um conjunto de linhas. COUNT(*) diz quantas linhas tem o conjunto; SUM(coluna) soma uma coluna de número dentro dele. Sozinhas, as duas resumem a tabela inteira numa linha só.
O GROUP BY é quem separa esse conjunto em grupos antes de contar e de somar: uma linha de resultado para cada valor diferente da coluna que ele agrupa, cada uma com a sua própria conta. É a diferença entre quanto a tabela toda soma e quanto cada um, cada carro, cada categoria soma.
Como se escreve
SELECT COUNT(*) FROM <tabela> WHERE <condição>;
SELECT SUM(<coluna>) FROM <tabela> WHERE <condição>;
SELECT <coluna>, COUNT(*), SUM(<outra coluna>)
FROM <tabela> GROUP BY <coluna>;
COUNT e SUM valem sozinhos, sem GROUP BY — só que aí resumem a tabela inteira numa linha. A terceira forma é as duas junto de um GROUP BY, que separa essa conta por grupo.
Exemplo para rodar
A tabela emprestimo tem mais duas colunas, que o capítulo passado não usou: leitor, quem pegou o livro emprestado, e dias, quantos dias ele ficou fora.
Todos os exemplos usam duas tabelinhas: livro (titulo, autor, ano, paginas) e emprestimo (livro, retirado_em, leitor, dias).
SELECT leitor, COUNT(*), SUM(dias) FROM emprestimo GROUP BY leitor;
| leitor | COUNT(*) | SUM(dias) |
|---|---|---|
| Denis | 2 | 17 |
| Marta | 2 | 8 |
Dicas
- COUNT(*) conta linhas, não importa o que tem dentro dos parênteses. SUM(dias) soma a coluna dias; para somar outra coisa, é só trocar o nome dela lá dentro.
- Toda coluna do SELECT que não está dentro de COUNT ou SUM tem que estar também no GROUP BY. Esqueceu? O SQLite não reclama: ele junta a tabela inteira num grupo só, e mostra um valor qualquer nessa coluna, como se fosse a resposta certa.
- GROUP BY vem depois do WHERE e antes do ORDER BY. O WHERE filtra as linhas primeiro; só depois disso o GROUP BY junta o que sobrou em grupos.
- GROUP BY aceita mais de uma coluna: GROUP BY leitor, livro junta pela combinação das duas, não por uma de cada vez. Nesta tabela pequena isso não muda a conta — não há duas linhas com a mesma dupla de valores —, mas é assim que, numa tabela maior, se separa por pessoa e por tipo ao mesmo tempo, cada combinação virando uma linha do resultado.
- A palavra dentro dos parênteses de SUM tem que ser uma coluna de número. leitor é texto: SUM(leitor) não faz sentido, e o SQLite não avisa — ele só devolve zero.
Erros comuns
- Você escreveu
SELECT leitor, COUNT(*), SUM(dias) FROM emprestimo;- O SQLite respondeu
Nenhum erro, e uma linha só: leitor mostra Marta, COUNT(*) mostra quatro e SUM(dias) mostra vinte e cinco.- Como consertar
- Faltou o GROUP BY leitor. Sem ele, COUNT e SUM leem a tabela inteira como um grupo só — quatro empréstimos, vinte e cinco dias somados —, e a coluna leitor mostra o nome de uma linha qualquer desse grupo, não uma resposta por pessoa.
- Você escreveu
SELECT leitor, COUNT * FROM emprestimo GROUP BY leitor;- O SQLite respondeu
near "FROM": syntax error- Como consertar
- COUNT precisa dos parênteses: COUNT(*), não COUNT *.
- Você escreveu
SELECT leitor, COUNT(*) FROM emprestimo GROUP leitor;- O SQLite respondeu
near "leitor": syntax error- Como consertar
- Faltou o BY entre GROUP e a coluna: GROUP BY leitor.
Veja também
Onde isso aparece no jogo
No jogo Delegacia SQL, COUNT, SUM e GROUP BY é o que resolve o inquérito 007, "Litro por litro". SISPOL, que aparece nas dicas, é o computador da delegacia do jogo.