【Funciona com Copiar e Colar】Guia Completo da Função COUNT do SQL! Do Básico ao Avançado
Ao desenvolver sites e aplicativos, você frequentemente precisa saber a "quantidade" de dados, como "Qual é o número total de usuários?" ou "Quantos tipos de produtos existem em uma categoria específica?". É nessas horas que a função COUNT() do SQL entra em ação.
COUNT() é uma função de agregação para contar o número de registros (linhas) em uma tabela. Parece simples à primeira vista, mas dependendo de como é usada, é uma função muito profunda que pode extrair várias informações. Neste artigo, explicaremos desde o uso básico até exemplos práticos e aplicados, com muitos "códigos que funcionam ao copiar e colar", para que até mesmo iniciantes que aspiram a ser criadores da web possam usá-la imediatamente.
O objetivo deste artigo é fazer com que todos vocês experimentem a emoção de "Uau, o SQL realmente funciona quando eu o escrevo!". Deixe a teoria complicada para depois! Primeiro, vamos copiar o código, executá-lo e sentir a diversão do SQL enquanto verificamos os resultados.
Primeiro, um aquecimento! Vamos preparar alguns dados de exemplo
Para experimentar o SQL, você precisa de uma tabela com dados. Desta vez, vamos criar uma tabela users simples, simulando uma "lista de usuários". A instrução SQL a seguir é para criar a tabela e inserir dados de exemplo.
Todos os códigos apresentados neste artigo têm como alvo esta tabela users.
-- Exclui a tabela se ela existir (para que você possa tentar várias vezes)
DROP TABLE IF EXISTS users;
-- Cria a tabela users
CREATE TABLE users (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
prefecture TEXT NOT NULL,
email TEXT
);
-- Insere os dados
INSERT INTO users (id, name, prefecture, email) VALUES
(1, '山田 太郎', '東京', 'yamada@example.com'),
(2, '鈴木 花子', '大阪', 'suzuki@example.com'),
(3, '佐藤 次郎', '東京', NULL),
(4, '伊藤 さくら', '福岡', 'ito@example.com'),
(5, '渡辺 三郎', '北海道', 'watanabe@example.com'),
(6, '高橋 四郎', '東京', 'takahashi@example.com'),
(7, '田中 美咲', '大阪', NULL);
Esta tabela possui colunas para ID, nome, prefeitura e endereço de e-mail. O ponto principal é que o email de Sato (ID 3) e Tanaka (ID 7) é NULL (ou seja, o dado está vazio). Isso será importante mais tarde para entender o comportamento da função COUNT().
【Básico 1】Contando todos os registros com `COUNT(*)`
Primeiro, o uso mais básico, COUNT(*). O asterisco (*) significa "todas as colunas", e COUNT(*) retorna o número total de registros na tabela. Use-o quando quiser simplesmente perguntar: "Quantos registros existem nesta tabela?".
Vamos contar imediatamente o número total de usuários na tabela users.
SELECT COUNT(*) FROM users;
Resultado da execução:
7
Como inserimos dados para 7 pessoas anteriormente, o resultado "7" foi retornado corretamente. Este é o "beabá" do COUNT().
【Básico 2】Contando com uma coluna específica: `COUNT(nome_da_coluna)`
A seguir, vamos ver como contar especificando um nome de coluna: COUNT(nome_da_coluna). Isso conta o número de registros onde a coluna especificada "possui um valor".
E aqui está um ponto importante: COUNT(nome_da_coluna) ignora valores NULL. Ou seja, ele não conta registros onde o dado está vazio.
Na tabela users de antes, vamos contar apenas o número de usuários que têm um endereço de e-mail registrado.
SELECT COUNT(email) FROM users;
Resultado da execução:
5
O resultado foi "5". Não corresponde ao "7" de COUNT(*), certo? Isso ocorre porque as duas pessoas cujo e-mail era NULL (Sato e Tanaka) foram excluídas da contagem.
Lembre-se bem desta diferença: COUNT(*) retorna o número simples de linhas, enquanto COUNT(nome_da_coluna) retorna "o número de linhas em que existem dados nessa coluna".
【Avançado 1】Dando um apelido ao resultado com `AS`
Por padrão, o resultado de COUNT() é exibido com um nome de coluna um pouco difícil de entender, como COUNT(*) ou COUNT(email). Isso pode ser inconveniente ao manusear os dados posteriormente.
Nesses casos, use AS para dar um nome mais claro (um alias) à coluna do resultado.
SELECT COUNT(*) AS total_users FROM users;
Resultado da execução:
total_users
-----------
7
Ao escrever AS total_users, o nome da coluna do resultado mudou para total_users. Agora, fica claro à primeira vista que este resultado é o "número total de usuários". Ao usar o resultado em um programa, você pode acessá-lo de forma intuitiva, como resultado['total_users'], o que é muito conveniente.
【Avançado 2】Contando sem duplicatas com `COUNT(DISTINCT nome_da_coluna)`
A seguir, COUNT(DISTINCT), que é muito usado em análises de sites, por exemplo. DISTINCT é uma palavra-chave que significa "excluir duplicatas", e ao usá-la, você pode contar o "número de tipos de dados únicos".
Por exemplo, pode responder à pergunta: "De quantos tipos de prefeituras diferentes os usuários deste site estão acessando?".
Na tabela users, há 3 pessoas de "Tóquio" e 2 de "Osaka", mas vamos contar como "tipos" de locais de origem.
SELECT COUNT(DISTINCT prefecture) AS unique_prefectures FROM users;
Resultado da execução:
unique_prefectures
------------------
4
O resultado foi "4". Como as prefeituras de origem na tabela users são "Tóquio", "Osaka", "Fukuoka" e "Hokkaido", 4 tipos no total, vemos que apenas os tipos foram contados corretamente.
As aplicações são infinitas, como descobrir o "número de categorias de produtos manuseados" em um site de e-commerce ou calcular o "número de visitantes únicos" a partir de logs de acesso.
【Avançado 3】Agregando por grupo com `GROUP BY`
O verdadeiro poder de COUNT() é revelado quando combinado com a cláusula GROUP BY. Usando GROUP BY, você pode agrupar registros que têm o mesmo valor em uma coluna especificada e aplicar COUNT() a cada um desses grupos.
"Quero saber o número de usuários por prefeitura de origem" — este é exatamente o momento para usar GROUP BY.
SELECT
prefecture,
COUNT(*) AS user_count
FROM
users
GROUP BY
prefecture;
Resultado da execução:
prefecture | user_count
-----------|------------
Osaka | 2
Hokkaido | 1
Tóquio | 3
Fukuoka | 1
Conseguimos obter uma lista com o número de usuários por prefeitura de origem! Ele cria grupos pela coluna prefecture e conta o número de registros em cada grupo com COUNT(*).
É uma técnica muito importante que serve como o primeiro passo na análise de sites, como para descobrir "de qual região vêm mais usuários?".
【Tópico Avançado】Adicionando condições aos resultados agregados com `HAVING`
Às vezes, você pode querer filtrar ainda mais os resultados agregados com GROUP BY. Por exemplo, em casos como "Quero exibir apenas as prefeituras com 2 ou mais usuários".
O que precisa de atenção aqui é que a cláusula WHERE, que filtra registros, é processada *antes* da agregação pelo GROUP BY, portanto, não pode ser usada no resultado da agregação (ex: `user_count`).
Se você deseja aplicar uma condição ao resultado após a agregação, use a cláusula HAVING.
SELECT
prefecture,
COUNT(*) AS user_count
FROM
users
GROUP BY
prefecture
HAVING
user_count >= 2;
Resultado da execução:
prefecture | user_count
-----------|------------
Osaka | 2
Tóquio | 3
Ao adicionar a condição HAVING user_count >= 2, apenas "Osaka" e "Tóquio", que têm 2 ou mais usuários, foram extraídos.
Lembre-se que WHERE é para condições em "registros individuais antes da agregação", e HAVING é para condições em "grupos após a agregação com GROUP BY".
【Área Experimental】Vamos executar SQL no seu navegador!
A espera acabou! Preparamos um ambiente onde você pode executar o SQL que aprendeu até agora com suas próprias mãos.
Copie todo o código HTML abaixo, salve-o em um arquivo com um nome como sql_test.html e abra-o em seu navegador. A tabela users apresentada no artigo já está preparada, então sinta-se à vontade para experimentar vários comandos SQL e se divertir vendo como os resultados mudam!
<!DOCTYPE html>
<html lang="pt">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Ambiente de Execução SQL para COUNT()</title>
<style>
body { font-family: sans-serif; line-height: 1.6; color: #333; max-width: 800px; margin: 2rem auto; padding: 0 1rem; }
h1 { color: #444; }
textarea { width: 100%; height: 150px; font-family: monospace; font-size: 16px; padding: 10px; border: 1px solid #ccc; border-radius: 4px; box-sizing: border-box; margin-bottom: 1rem; }
button { background-color: #007bff; color: white; border: none; padding: 10px 20px; font-size: 16px; border-radius: 4px; cursor: pointer; }
button:hover { background-color: #0056b3; }
button:disabled { background-color: #ccc; cursor: not-allowed; }
#result-container { margin-top: 2rem; border: 1px solid #ddd; padding: 1rem; border-radius: 4px; background: #f9f9f9; min-height: 50px; }
#error-message { color: #d9534f; font-weight: bold; }
table { border-collapse: collapse; width: 100%; margin-top: 1rem; }
th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
th { background-color: #f2f2f2; }
</style>
<script src="https://cdnjs.cloudflare.com/ajax/libs/sql.js/1.10.3/sql-wasm.js"></script>
</head>
<body>
<h1>Vamos experimentar o SQL!</h1>
<p>Insira sua instrução SQL na área de texto abaixo e pressione o botão "Executar". Experimente os vários comandos SQL apresentados no artigo!</p>
<textarea id="sql-input">SELECT prefecture, COUNT(*) AS user_count
FROM users
GROUP BY prefecture
HAVING user_count >= 2;</textarea>
<button id="execute-btn">Executar</button>
<div id="result-container">
<p id="error-message"></p>
<div id="result-output"></div>
</div>
<script>
const sqlInput = document.getElementById('sql-input');
const executeBtn = document.getElementById('execute-btn');
const errorMsg = document.getElementById('error-message');
const resultOutput = document.getElementById('result-output');
let db;
async function initDb() {
executeBtn.disabled = true;
executeBtn.textContent = 'Preparando...';
try {
const SQL = await initSqlJs({
locateFile: file => `https://cdnjs.cloudflare.com/ajax/libs/sql.js/1.10.3/${file}`
});
db = new SQL.Database();
// Setup initial table and data
const setupSql = `
DROP TABLE IF EXISTS users;
CREATE TABLE users (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
prefecture TEXT NOT NULL,
email TEXT
);
INSERT INTO users (id, name, prefecture, email) VALUES
(1, '山田 太郎', '東京', 'yamada@example.com'),
(2, '鈴木 花子', '大阪', 'suzuki@example.com'),
(3, '佐藤 次郎', '東京', NULL),
(4, '伊藤 さくら', '福岡', 'ito@example.com'),
(5, '渡辺 三郎', '北海道', 'watanabe@example.com'),
(6, '高橋 四郎', '東京', 'takahashi@example.com'),
(7, '田中 美咲', '大阪', NULL);
`;
db.run(setupSql);
executeBtn.disabled = false;
executeBtn.textContent = 'Executar';
resultOutput.innerHTML = '<p>Pronto! Insira seu SQL e execute.</p>';
} catch (err) {
errorMsg.textContent = 'Falha ao inicializar o banco de dados: ' + err.message;
console.error(err);
}
}
function executeSql() {
if (!db) return;
const sql = sqlInput.value;
errorMsg.textContent = '';
resultOutput.innerHTML = '';
try {
const results = db.exec(sql);
if (results.length === 0) {
resultOutput.innerHTML = '<p>A consulta foi bem-sucedida, mas nenhum conjunto de resultados foi retornado (ex: INSERT, UPDATE, etc.).</p>';
return;
}
results.forEach(result => {
const table = document.createElement('table');
const thead = document.createElement('thead');
const tbody = document.createElement('tbody');
const headerRow = document.createElement('tr');
result.columns.forEach(colName => {
const th = document.createElement('th');
th.textContent = colName;
headerRow.appendChild(th);
});
thead.appendChild(headerRow);
result.values.forEach(row => {
const bodyRow = document.createElement('tr');
row.forEach(cellValue => {
const td = document.createElement('td');
td.textContent = cellValue === null ? 'NULL' : cellValue;
bodyRow.appendChild(td);
});
tbody.appendChild(bodyRow);
});
table.appendChild(thead);
table.appendChild(tbody);
resultOutput.appendChild(table);
});
} catch (err) {
errorMsg.textContent = 'Erro de SQL: ' + err.message;
console.error(err);
}
}
executeBtn.addEventListener('click', executeSql);
initDb();
</script>
</body>
</html>
【Experimente!】
- Tente contar o número de usuários que não têm um endereço de e-mail registrado. (Dica: a diferença entre `COUNT(*)` e `COUNT(email)`)
- Tente contar apenas os usuários cuja prefeitura de origem é 'Tóquio'. (Dica: use a cláusula `WHERE`)
- Tente executar uma nova instrução `INSERT` para adicionar dados e, em seguida, verifique se a contagem aumenta com `COUNT(*)`.
Pontos de Atenção e Dicas
COUNT(*)vsCOUNT(1)vsCOUNT(nome_da_coluna)-
Você pode encontrar a sintaxe
COUNT(1). Isso significa atribuir a constante "1" a cada linha e contar esse número. Na maioria dos bancos de dados, não há diferença no comportamento ou no desempenho entreCOUNT(*)eCOUNT(1). Ambos contam todas as linhas. Como mencionado anteriormente,COUNT(nome_da_coluna)não conta valoresNULL, então vamos confirmar novamente que o objetivo é diferente. Se estiver em dúvida, é recomendável usarCOUNT(*)(se quiser contar todas as linhas) ouCOUNT(nome_da_coluna)(se quiser contar valores não nulos), pois a intenção é mais clara. - Desempenho
-
Executar
COUNT(*)em tabelas enormes com milhões ou dezenas de milhões de registros pode levar tempo. Isso ocorre porque uma contagem total sem condições específicas precisa varrer todos os dados da tabela. Se for necessário obter a contagem total com frequência, outros métodos (como preparar uma tabela de resumo separada) podem ser considerados, mas, por enquanto, não há problema em lembrar disso como um uso básico.
Funções Relacionadas: Outras Funções de Agregação
Depois de aprender COUNT(), é fácil aprender outras funções de agregação. Elas também são muito poderosas quando combinadas com GROUP BY.
SUM(nome_da_coluna): Calcula o valor total de uma coluna numérica. (Ex: total de vendas)AVG(nome_da_coluna): Calcula o valor médio de uma coluna numérica. (Ex: idade média, preço médio unitário)MAX(nome_da_coluna): Obtém o valor máximo de uma coluna. (Ex: temperatura máxima, pontuação mais alta)MIN(nome_da_coluna): Obtém o valor mínimo de uma coluna. (Ex: preço mais baixo)
Por exemplo, se você quiser saber o valor máximo do ID do usuário, seria assim:
SELECT MAX(id) AS latest_user_id FROM users;
Resumo
Desta vez, examinamos rapidamente a função COUNT(), que conta o número de registros, desde seu uso básico até técnicas avançadas.
COUNT(*): Conta o número total de registros em uma tabela.COUNT(nome_da_coluna): Conta o número de registros nãoNULLem uma coluna especificada.COUNT(DISTINCT nome_da_coluna): Conta o número de tipos de dados únicos, excluindo duplicatas.AS alias: Dá um apelido claro à coluna de resultado.GROUP BY: Combina comCOUNT()ao agregar por grupos.
COUNT() é o primeiro passo para analisar dados e obter insights. Por favor, tente o código deste artigo várias vezes e pegue o jeito de "contar dados". Ser capaz de usar SQL ampliará muito o mundo que você vê. Vamos continuar aprendendo enquanto nos divertimos!