devgameschool

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
2 linhas no resultado

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.

Jogar Delegacia SQL