[SQL] Domine a cláusula LIMIT: controle total da exibição de dados do básico à paginação
“Top 5 de novos produtos”, “Top 10 de artigos populares”, “Primeira página dos resultados de busca”… Em sites e aplicativos, é muito comum exibir apenas uma parte de um grande conjunto de dados. A cláusula poderosa do SQL que torna isso possível é LIMIT.
Este artigo é voltado para criadores web e explica desde o uso básico da cláusula LIMIT até a implementação da técnica essencial de paginação no desenvolvimento web. Inclui exemplos de código práticos e um ambiente interativo de execução que você pode copiar e colar. Experimente com as próprias mãos e adquira essa ferramenta poderosa para manipular dados com eficiência!
Vamos aquecer primeiro! Usaremos dados de exemplo novamente
Antes de começarmos, usaremos novamente a tabela de produtos (products) de uma loja online fictícia chamada “Web Creator's Mart”. Se você leu o nosso artigo sobre ORDER BY, provavelmente vai reconhecer.
O SQL abaixo cria a tabela e insere os dados. Você pode testá-lo no seu ambiente local ou usá-lo no “ambiente de execução interativo” que será mostrado mais adiante. Dê uma olhada antes de prosseguir.
-- Criar tabela de produtos
CREATE TABLE products (
id INT,
name VARCHAR(255),
category VARCHAR(255),
price INT,
release_date DATE
);
-- Inserir dados de exemplo (7 registros)
INSERT INTO products (id, name, category, price, release_date) VALUES
(1, 'Almofada fofinha', 'Decoração', 3200, '2023-04-15'),
(2, 'Protetor auricular para foco', 'Gadgets', 7800, '2023-11-01'),
(3, 'Caderno criativo', 'Papelaria', 1200, '2022-08-20'),
(4, 'Teclado iluminado', 'Gadgets', 15000, '2023-06-30'),
(5, 'Cadeira super confortável', 'Decoração', 32000, '2022-11-10'),
(6, 'Caneta esferográfica suave', 'Papelaria', 1200, '2023-09-01'),
(7, 'Caneca do criador', 'Utensílios', 2500, '2023-04-15');
Tudo pronto? Então vamos mergulhar no mundo da cláusula LIMIT!
Conceitos básicos da cláusula LIMIT: especificando a quantidade de registros
O uso mais simples da cláusula LIMIT é limitar o número máximo de registros (linhas) retornados. A sintaxe é muito fácil: basta adicionar LIMIT quantidade ao final da instrução SELECT.
Por exemplo, vamos obter apenas 3 registros da tabela products.
SELECT * FROM products LIMIT 3;
Ao executar esse comando, os 3 primeiros registros armazenados na tabela serão retornados. É muito intuitivo. No entanto, há um ponto importante: sem uma ordenação explícita, não é garantido quais 3 registros serão retornados. A ordem pode variar a cada execução dependendo da forma como o banco organiza os dados internamente.
O verdadeiro poder da cláusula LIMIT é revelado quando usada em conjunto com ORDER BY, como vimos no artigo anterior.
A dupla imbatível! ORDER BY + LIMIT para buscar os “Top N registros”
Obter os “Top N registros”, como “os 3 produtos mais caros” ou “os 5 lançamentos mais recentes”, é um requisito comum em sites. Isso pode ser feito ao ordenar os dados com ORDER BY e limitar a quantidade com LIMIT.
Vamos buscar os 3 produtos mais caros. Usamos ORDER BY price DESC para ordenar do maior para o menor preço, e LIMIT 3 para pegar os 3 primeiros.
-- Buscar os 3 produtos mais caros
SELECT * FROM products ORDER BY price DESC LIMIT 3;
Viu só? Você deverá obter “Cadeira com conforto supremo”, “Teclado iluminado” e “Protetores auriculares para foco” nessa ordem. Essa é a fórmula de ouro: defina a ordem com ORDER BY e recorte com LIMIT. Lembre-se de sempre usar os dois juntos!
Agora, vamos buscar os “2 produtos mais novos”, ordenando por data de lançamento (release_date).
-- Buscar os 2 produtos mais recentes pela data de lançamento
SELECT * FROM products ORDER BY release_date DESC LIMIT 2;
Deslocando o início da busca com OFFSET
Um grande parceiro da cláusula LIMIT é o OFFSET. Como o nome sugere, OFFSET permite “pular uma quantidade de registros antes de começar a retornar os dados”.
Por exemplo, imagine que você deseja “pular o produto mais caro e obter apenas o 2º e 3º mais caros”. OFFSET resolve isso com facilidade.
-- Ordenar por preço decrescente, pular o primeiro e obter os próximos 2
SELECT * FROM products ORDER BY price DESC LIMIT 2 OFFSET 1;
Esse comando SQL funciona da seguinte forma:
ORDER BY price DESC: ordena os produtos do mais caro para o mais barato.OFFSET 1: pula o primeiro produto (mais caro).LIMIT 2: retorna os dois seguintes (2º e 3º mais caros).
Essa combinação de LIMIT e OFFSET é a base da técnica de paginação, que veremos a seguir.
Avançado: implementando paginação com LIMIT e OFFSET
Paginação é o processo de dividir grandes volumes de dados em várias páginas, como listas de produtos ou posts de blog. Você certamente já viu navegadores com “1, 2, 3, 4, 5, ... Próxima”.
Isso é feito usando LIMIT e OFFSET. Suponha que você queira exibir 3 produtos por página:
- Página 1: obter os primeiros 3 registros (pular 0)
- Página 2: pular os primeiros 3 e obter os próximos 3
- Página 3: pular os primeiros 6 e obter os próximos 3
As consultas SQL seriam assim. Vamos ordenar por id para manter a consistência.
【SQL da Página 1】
-- Página 1: pular 0 e obter 3 registros
SELECT * FROM products ORDER BY id LIMIT 3 OFFSET 0;
【SQL da Página 2】
-- Página 2: pular 3 e obter 3 registros
SELECT * FROM products ORDER BY id LIMIT 3 OFFSET 3;
【SQL da Página 3】
-- Página 3: pular 6 e obter 3 registros
SELECT * FROM products ORDER BY id LIMIT 3 OFFSET 6;
Percebeu? O valor de LIMIT (itens por página) é sempre 3. Já o valor de OFFSET cresce como 0, 3, 6, .... Podemos usar a seguinte fórmula para calcular:
OFFSET = (número da página atual - 1) × itens por página
Com essa fórmula implementada no seu código, é possível criar paginações dinâmicas. Mas nada melhor que ver isso na prática. Vamos testar um ambiente interativo na próxima seção!
【Vamos praticar!】Execute SQL diretamente no navegador
Obrigado por esperar! Preparamos um ambiente interativo onde você pode executar SQL diretamente no seu navegador. Com isso, você poderá experimentar os diferentes padrões da cláusula LIMIT apresentados neste artigo com suas próprias mãos.
Copie todo o código abaixo, salve com um nome como index.html e abra no navegador. Cole os exemplos SQL deste artigo na área de texto e clique no botão "Executar SQL".
<!DOCTYPE html>
<html lang="pt">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Ambiente de Prática SQL</title>
<style>
body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; line-height: 1.6; color: #333; max-width: 800px; margin: 2rem auto; padding: 0 1rem; }
h1, h2 { color: #444; border-bottom: 2px solid #eee; padding-bottom: 0.3em;}
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; padding: 10px 20px; border: none; border-radius: 4px; cursor: pointer; font-size: 16px; }
button:hover { background-color: #0056b3; }
#result-container { margin-top: 1.5rem; min-height: 100px;}
table { width: 100%; border-collapse: collapse; margin-top: 1rem; }
th, td { border: 1px solid #ddd; padding: 10px; text-align: left; }
th { background-color: #f8f8f8; }
#error-message { color: red; font-weight: bold; margin-top: 1rem; }
</style>
</head>
<body>
<h1>Aprenda SQL na prática! Área de treino LIMIT</h1>
<p>Digite sua instrução SQL na área abaixo e clique no botão "Executar SQL". Experimente os vários exemplos apresentados no artigo!</p>
<textarea id="sql-input">-- Cole aqui seu SQL para testar!
-- Exemplo: Top 3 produtos mais caros
SELECT * FROM products ORDER BY price DESC LIMIT 3;</textarea>
<button onclick="executeQuery()">Executar SQL</button>
<h2>Resultado da Execução</h2>
<div id="result-container"></div>
<div id="error-message"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/sql.js/1.10.3/sql-wasm.js"></script>
<script>
let db;
async function initDb() {
try {
const SQL = await initSqlJs({
locateFile: file => `https://cdnjs.cloudflare.com/ajax/libs/sql.js/1.10.3/${file}`
});
db = new SQL.Database();
const setupSQL = `
CREATE TABLE products (id INT, name VARCHAR(255), category VARCHAR(255), price INT, release_date DATE);
INSERT INTO products (id, name, category, price, release_date) VALUES
(1, 'Almofada Fofa', 'Decoração', 3200, '2023-04-15'),
(2, 'Protetor de Ouvido para Concentração', 'Gadgets', 7800, '2023-11-01'),
(3, 'Caderno de Ideias Brilhantes', 'Papelaria', 1200, '2022-08-20'),
(4, 'Teclado Iluminado', 'Gadgets', 15000, '2023-06-30'),
(5, 'Cadeira Ultra Confortável', 'Decoração', 32000, '2022-11-10'),
(6, 'Caneta Esferográfica Suave', 'Papelaria', 1200, '2023-09-01'),
(7, 'Caneca Criativa', 'Utensílios', 2500, '2023-04-15');
`;
db.run(setupSQL);
executeQuery();
} catch (e) {
document.getElementById('error-message').textContent = 'Erro ao inicializar o banco de dados: ' + e.message;
}
}
function executeQuery() {
const sqlInput = document.getElementById('sql-input').value;
const resultContainer = document.getElementById('result-container');
const errorMessage = document.getElementById('error-message');
resultContainer.innerHTML = '';
errorMessage.innerHTML = '';
try {
const results = db.exec(sqlInput);
if (results.length > 0) {
resultContainer.appendChild(createTable(results[0]));
} else {
resultContainer.innerHTML = '<p>A consulta foi bem-sucedida, mas não retornou nenhum resultado. (ex: CREATE TABLE, INSERT)</p>';
}
} catch (e) {
errorMessage.textContent = 'Erro: ' + e.message;
}
}
function createTable(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(rowData => {
const tr = document.createElement('tr');
rowData.forEach(cellData => {
const td = document.createElement('td');
td.textContent = cellData;
tr.appendChild(td);
});
tbody.appendChild(tr);
});
table.appendChild(thead);
table.appendChild(tbody);
return table;
}
initDb();
</script>
</body>
</html>
Complemento: variações de dialeto entre bancos de dados
A sintaxe LIMIT ... OFFSET ... explicada neste artigo é um formato padrão suportado por muitos bancos de dados como MySQL, PostgreSQL e SQLite. No entanto, alguns bancos de dados utilizam sintaxes diferentes (dialetos), então vamos apresentar algumas variações como referência.
No caso do SQL Server
O Microsoft SQL Server usava a cláusula TOP nas versões antigas, mas as versões mais recentes recomendam o uso de OFFSET ... FETCH ....
-- Paginação no SQL Server (pular 3 registros e buscar os próximos 3)
SELECT * FROM products
ORDER BY id
OFFSET 3 ROWS
FETCH NEXT 3 ROWS ONLY;
No caso do Oracle
O banco de dados Oracle também utiliza a sintaxe OFFSET ... FETCH ..., semelhante ao SQL Server.
-- Paginação no Oracle (pular 3 registros e buscar os próximos 3)
SELECT * FROM products
ORDER BY id
OFFSET 3 ROWS
FETCH NEXT 3 ROWS ONLY;
Como você pode ver, a sintaxe pode variar entre os bancos de dados, mas o conceito básico (especificar quantos registros pular e quantos buscar) é exatamente o mesmo.
Resumo: Quem domina o LIMIT, domina a exibição de dados!
Neste artigo, exploramos a cláusula LIMIT do SQL e sua parceira OFFSET, desde o básico até o avançado. Vamos revisar os pontos mais importantes de hoje:
LIMITrestringe o número de registros retornados.- Combinado com
ORDER BY, é um padrão essencial para obter os "N primeiros" resultados. OFFSETdefine a posição inicial da busca (pula N registros desde o início).- Combinar
LIMITcomOFFSETpermite implementar paginação, fundamental no desenvolvimento web.
Obter apenas os dados necessários, na quantidade certa, ajuda a manter a performance do banco de dados e oferece uma experiência de usuário fluida. Experimente o ambiente de demonstração e domine totalmente o seu funcionamento!