Manual SQL: queries básicas e avançadas
1. Introdução: A Linguagem Universal dos Dados
SQL (Structured Query Language) é a linguagem padrão para manipulação de dados. Permite consultar, inserir, atualizar e remover dados, facilitando gestão e análise.
Usado em desenvolvimento web, análise de dados (insights) e administração de bancos (manutenção e segurança).
Tutorial prático e estruturado: guia do básico ao avançado em SQL, com exemplos e exercícios reais.
Próximo passo: configurar ambiente e entender a estrutura de bancos para interação com dados.
2. Primeiros Passos: Ambiente e Estrutura Básica
Para usar SQL, é essencial entender a organização de dados e configurar um ambiente de prática.
Em SGBDRs, dados se organizam em tabelas (planilhas com linhas e colunas).
- Tabelas: Estruturas que armazenam dados de uma entidade (Ex: "Produtos").
- Colunas: Atributos de dados com
tipo de dado(ex: texto, número). Ex:id_produto,nome_produto,preco. - Linhas (Registros): Entradas individuais na tabela.
Para praticar, use DB Browser for SQLite (gratuito, local) ou Plataformas online (ex: SQL Fiddle/DB-Fiddle), sem configuração de servidor.
Crie o esquema de exemplo:
-- Criação da tabela Produtos
CREATE TABLE Produtos (
id_produto INTEGER PRIMARY KEY,
nome_produto TEXT NOT NULL,
preco REAL,
quantidade_estoque INTEGER
);
-- Inserção de alguns dados de exemplo
INSERT INTO Produtos (id_produto, nome_produto, preco, quantidade_estoque) VALUES
(1, 'Laptop XYZ', 1200.00, 50),
(2, 'Mouse Sem Fio', 25.50, 200),
(3, 'Teclado Mecânico', 99.99, 75),
(4, 'Monitor UltraWide', 450.00, 30);
A seleção de dados (SELECT) é fundamental em SQL, usando SELECT (colunas) e FROM (tabela).
Para selecionar todas as colunas:
SELECT *
FROM Produtos;
Para colunas específicas:
SELECT nome_produto, preco
FROM Produtos;
Para filtrar dados, use a cláusula WHERE:
-- Seleciona produtos com preço superior a 100
SELECT nome_produto, preco, quantidade_estoque
FROM Produtos
WHERE preco > 100.00;
Com o ambiente e a estrutura prontos, é possível selecionar e filtrar dados.
3. Dominando o SELECT: A Arte de Consultar Dados
A SELECT é a principal ferramenta para extrair dados e insights de bancos relacionais. Comentários SQL usam --. Define o que e de onde selecionar.
Colunas e Origem
SELECT *: Retorna todas as colunas.SELECT * FROM Clientes;SELECT column1, column2: Seleciona colunas, otimizando desempenho e legibilidade.SELECT Nome, Email FROM Clientes;- Renomear (
AS): Renomeia colunas para clareza.SELECT Nome AS NomeCliente, Email AS ContatoPrincipal FROM Clientes; FROM table_name: Indica atabela.SELECT NomeProduto, Preco FROM Produtos;
Filtragem de Linhas com WHERE
WHERE filtra linhas por condições.
- Operadores de Comparação:
=,<>,>,<,>=,<=.SELECT Nome, Preco FROM Produtos WHERE Preco > 50; - Lógicos (
AND,OR,NOT): Combinam condições (AND: ambas;OR: uma;NOT: nega).SELECT NomeProduto, Preco FROM Produtos WHERE Preco > 50 AND Estoque < 10;
Operadores de Filtragem Especial
LIKE: Busca padrões (%: zero/mais;_: um caractere).SELECT Nome FROM Clientes WHERE Nome LIKE 'João%';IN: Especifica lista de valores.SELECT Categoria FROM Produtos WHERE Categoria IN ('Eletrônicos', 'Livros');BETWEEN: Seleciona valores em um intervalo (limites inclusos).SELECT DataVenda FROM Vendas WHERE DataVenda BETWEEN '2023-01-01' AND '2023-01-31';IS NULL/IS NOT NULL: Verifica valores nulos.SELECT Nome FROM Clientes WHERE Telefone IS NULL;
Agregação e Análise de Dados
SELECT, com Funções de Agregação e GROUP BY, sumariza dados para análise e insights.
- Funções de Agregação (
COUNT(),SUM(),AVG(),MIN(),MAX()) calculam sobre um conjunto de linhas.SELECT COUNT(*) AS TotalClientes FROM Clientes; SELECT AVG(Preco) AS PrecoMedioProdutos FROM Produtos; GROUP BY: Agrupa linhas para funções de agregação (ex: total por categoria).SELECT Categoria, COUNT(*) AS TotalProdutos FROM Produtos GROUP BY Categoria;HAVING: Filtra grupos (GROUP BY) após agregação (diferente deWHERE).SELECT Categoria, COUNT(*) FROM Produtos GROUP BY Categoria HAVING COUNT(*) > 5;
Ordenação (ORDER BY)
Ordena resultados (ASC padrão, DESC).
SELECT NomeProduto, Preco FROM Produtos ORDER BY Preco DESC;
Valores Únicos (DISTINCT)
Obtém valores únicos de colunas.
SELECT DISTINCT Cidade FROM Clientes;
Limitação (LIMIT/TOP)
Limita o número de linhas (sintaxe varia por SGBD).
LIMIT(MySQL/PostgreSQL):SELECT NomeProduto, Preco FROM Produtos ORDER BY Preco DESC LIMIT 5;TOP(SQL Server):SELECT TOP 5 NomeProduto, Preco FROM Produtos ORDER BY Preco DESC;
SELECT é crucial para consultar dados e insights. Para manipulação, SQL usa INSERT, UPDATE, DELETE.
4. Manipulação de Dados (DML): Inserir, Atualizar e Deletar
A DML (Data Manipulation Language) gerencia dados em bancos de dados, cobrindo INSERT, UPDATE e DELETE.
Inserir Dados: INSERT INTO
INSERT INTO adiciona linhas (registros) a tabelas. Duas sintaxes:
-
Todas as colunas: Insere valores em todas as colunas, em ordem.
INSERT INTO NomeTabela VALUES (valor1, valor2, valor3, ...);Exemplo:
INSERT INTO Produtos VALUES (101, 'Teclado Mecânico', 350.00, 50); -
Colunas específicas: Especifica colunas (útil para nulos/padrão ou ordem).
INSERT INTO NomeTabela (Coluna1, Coluna2, Coluna3) VALUES (valor1, valor2, valor3);Exemplo:
INSERT INTO Produtos (ID_Produto, Nome, Preco) VALUES (102, 'Mouse Sem Fio', 120.00);
Atualizar Dados: UPDATE
UPDATE modifica dados em uma ou mais linhas de uma tabela.
UPDATE NomeTabela
SET Coluna1 = NovoValor1, Coluna2 = NovoValor2, ...
WHERE Condicao;
Exemplo:
UPDATE Produtos
SET Preco = 380.00
WHERE ID_Produto = 101;
Atenção: Cláusula WHERE
A cláusula WHERE é crítica: define quais registros modificar. Omiti-la modificará todas as linhas, com consequências desastrosas.
Exemplo de ALERTA:
UPDATE Produtos
SET Estoque = 0; -- CUIDADO! Isso zeraria o estoque de TODOS os produtos!
Sempre verifique a condição WHERE com cuidado.
Deletar Dados: DELETE FROM
DELETE FROM remove linhas de uma tabela.
DELETE FROM NomeTabela
WHERE Condicao;
Exemplo:
DELETE FROM Produtos
WHERE ID_Produto = 102;
Atenção: Cláusula WHERE
No DELETE FROM, a cláusula WHERE é igualmente crítica: define quais registros remover. Omiti-la removerá todas as linhas, esvaziando a tabela.
Exemplo de ALERTA:
DELETE FROM Produtos; -- CUIDADO! Isso deletaria TODOS os produtos da tabela!
Use a cláusula WHERE com extremo cuidado. Recomenda-se um SELECT prévio com a mesma condição.
Segurança e Controle: Transações (COMMIT e ROLLBACK)
SQL oferece Transações para segurança e controle DML. Elas são sequências de operações DML tratadas como unidade, que podem ser salvas (COMMIT) ou desfeitas (ROLLBACK), retornando ao estado anterior.
BEGIN TRANSACTION; -- Ou START TRANSACTION;
-- Seus comandos DML aqui (INSERT, UPDATE, DELETE)
-- Salvar as mudanças:
-- COMMIT;
-- Desfazer as mudanças:
-- ROLLBACK;
Exemplo de uso de transação:
BEGIN TRANSACTION;
UPDATE Produtos
SET Estoque = Estoque - 10
WHERE ID_Produto = 101;
-- Se a atualização acima não deveria ser mantida:
ROLLBACK; -- 10 unidades não são removidas do estoque.
-- OU, se correta:
-- COMMIT; -- 10 unidades são definitivamente removidas do estoque.
Transações são recomendadas para DML complexas, garantindo segurança e integridade dos dados.
Com os comandos DML, gerenciamos registros. Para análise e sumarização, a próxima seção aborda agregação e agrupamento.
5. Agregação e Agrupamento: Sumarizando Informações
Para extrair insights de dados, a sumarização é essencial. Funções de agregação e agrupamento no SQL calculam estatísticas importantes.
Funções de Agregação operam sobre linhas, retornando um valor sumarizado. Principais:
COUNT(): Conta linhas/valores.SUM(): Soma valores numéricos.AVG(): Calcula a média numérica.MIN(): Retorna o menor valor.MAX(): Retorna o maior valor.
Operam sobre todas as linhas por padrão; poder expande com GROUP BY.
GROUP BY agrupa linhas por uma ou mais colunas, aplicando agregações por grupo. Ideal para, e.g., total de vendas por categoria.
Exemplos GROUP BY:
- Vendas por categoria:
SELECT CategoriaProduto, SUM(ValorVenda) AS TotalVendas FROM Vendas GROUP BY CategoriaProduto; - Clientes por cidade:
SELECT Cidade, COUNT(IDCliente) AS NumeroClientes FROM Clientes GROUP BY Cidade; - Idade média por depto:
SELECT Departamento, AVG(Idade) AS MediaIdade FROM Funcionarios GROUP BY Departamento;
Após agrupar, HAVING filtra grupos por resultados agregados. Distinção:
WHERE: filtra linhas antes da agregação.HAVING: filtra grupos após agregar.
Exemplos HAVING:
- Cidades com >100 clientes:
SELECT Cidade, COUNT(IDCliente) AS NumeroClientes FROM Clientes GROUP BY Cidade HAVING COUNT(IDCliente) > 100; - Categorias com vendas > R$ 5000:
SELECT CategoriaProduto, SUM(ValorVenda) AS TotalVendas FROM Vendas GROUP BY CategoriaProduto HAVING SUM(ValorVenda) > 5000;
Dominar agregação e agrupamento é essencial para transformar dados em resumos significativos no SQL.
Próximo: JOINS conectam dados de tabelas diferentes.
6. Unindo Forças: Trabalhando com Múltiplas Tabelas (JOINs)
Bancos de dados relacionais organizam dados em tabelas interconectadas. JOINs as unificam.
Tabelas são unidas por Chaves Primárias (PK) e Chaves Estrangeiras (FK). A PK identifica registros; a FK referencia a PK de outra tabela, vinculando-as. Ex: Produtos.categoria_id (FK) aponta para Categorias.id (PK).
Combinam linhas de tabelas por colunas relacionadas. Tipos de JOINs:
INNER JOIN
Retorna linhas correspondentes em ambas as tabelas.
Sintaxe Básica:
SELECT colunas FROM Tabela1 INNER JOIN Tabela2 ON Tabela1.pk = Tabela2.fk;
Exemplo:
SELECT P.NomeProduto, C.NomeCategoria
FROM Produtos AS P
INNER JOIN Categorias AS C ON P.CategoriaID = C.CategoriaID;
LEFT JOIN (ou LEFT OUTER JOIN)
Retorna todas as linhas da tabela "esquerda" e as correspondentes da "direita". NULL para não correspondência.
Sintaxe Básica:
SELECT colunas FROM TabelaEsquerda LEFT JOIN TabelaDireita ON TabelaEsquerda.pk = TabelaDireita.fk;
Exemplo:
SELECT Cl.NomeCliente, Ped.DataPedido
FROM Clientes AS Cl
LEFT JOIN Pedidos AS Ped ON Cl.ClienteID = Ped.ClienteID;
RIGHT JOIN (ou RIGHT OUTER JOIN)
Retorna todas as linhas da tabela "direita" e as correspondentes da "esquerda". NULL para não correspondência. Análogo ao LEFT JOIN, menos comum (reversível).
Sintaxe Básica:
SELECT colunas FROM TabelaEsquerda RIGHT JOIN TabelaDireita ON TabelaEsquerda.pk = TabelaDireita.fk;
Exemplo:
SELECT C.NomeCategoria, P.NomeProduto
FROM Produtos AS P
RIGHT JOIN Categorias AS C ON P.CategoriaID = C.CategoriaID;
FULL OUTER JOIN
Retorna todas as linhas de ambas as tabelas, com NULL para não correspondência. Combina LEFT e RIGHT JOIN. Suporte limitado em alguns SGBDs (ex: MySQL).
Sintaxe Básica:
SELECT colunas FROM Tabela1 FULL OUTER JOIN Tabela2 ON Tabela1.pk = Tabela2.fk;
Exemplo Conceitual:
SELECT F.NomeFuncionario, D.NomeDepartamento
FROM Funcionarios AS F
FULL OUTER JOIN Departamentos AS D ON F.DepartamentoID = D.DepartamentoID;
Self-JOIN
Une uma tabela a si mesma, útil para relacionar registros (ex: funcionários e gerentes). Requer aliases.
Exemplo:
SELECT
Func.Nome AS NomeFuncionario,
Ger.Nome AS NomeGerente
FROM
Funcionarios AS Func
INNER JOIN
Funcionarios AS Ger ON Func.GerenteID = Ger.FuncionarioID;
Encadeamento de Múltiplos JOINs
Combina informações de múltiplas tabelas, encadeando JOINs. A ordem é importante, especialmente com LEFT/RIGHT JOINs.
Exemplo:
SELECT
P.NomeProduto,
C.NomeCategoria,
F.NomeFornecedor
FROM
Produtos AS P
INNER JOIN
Categorias AS C ON P.CategoriaID = C.CategoriaID
INNER JOIN
Fornecedores AS F ON P.FornecedorID = F.FornecedorID;
Aliases de Tabelas
Essenciais ao unir múltiplas tabelas, para legibilidade e evitar ambiguidades. Usam nomes temporários curtos (AS ou ).
Sintaxe:
SELECT P.NomeProduto, C.NomeCategoria
FROM Produtos AS P -- 'P' é o alias para 'Produtos'
INNER JOIN Categorias C ON P.CategoriaID = C.CategoriaID; -- 'C' é o alias para 'Categorias'
Considerações de Performance
Para otimizar JOINs em grandes volumes de dados, colunas ON (PKs e FKs) devem ser indexadas. Índices aumentam a eficiência.
Nota Importante: Sintaxe Implícita de JOIN
A sintaxe implícita (FROM Tabela1, Tabela2 WHERE condicao) é desencorajada. A sintaxe explícita (INNER JOIN, LEFT JOIN, etc.) é preferível pela clareza e manutenção.
Exemplo Antigo (não recomendado):
SELECT P.NomeProduto, C.NomeCategoria
FROM Produtos P, Categorias C
WHERE P.CategoriaID = C.CategoriaID;
Dominar JOINs permite consultas complexas sobre dados interligados. A seguir, exploraremos subconsultas e CTEs.
7. Consultas Aninhadas e CTEs: Escalando a Complexidade
SQL oferece subconsultas (subqueries) e CTEs para manipular dados complexos e lógicas sofisticadas.
Subconsultas (Subqueries)
Subconsultas são queries SQL aninhadas que retornam resultados à consulta externa, usadas em:
SELECT: Retorna valor escalar por linha (ex: média geral).SELECT ProdutoID, NomeProduto, (SELECT AVG(PrecoUnitario) FROM Produtos) AS PrecoMedioGeral FROM Produtos;FROM: Trata o resultado como tabela temporária para pré-processamento de dados.SELECT t1.Categoria, t1.TotalVendasCategoria FROM (SELECT Categoria, SUM(TotalVendas) AS TotalVendasCategoria FROM Vendas GROUP BY Categoria) AS t1 WHERE t1.TotalVendasCategoria > 10000;WHERE/HAVING: Filtra resultados com base em outra consulta.SELECT NomeCliente FROM Clientes WHERE ClienteID IN (SELECT ClienteID FROM Pedidos WHERE DataPedido BETWEEN '2023-12-01' AND '2023-12-31');
Tipos de Subconsultas:
- Escalares: Retornam um único valor.
- De Coluna Única: Retornam uma coluna (várias linhas), usadas com
IN,EXISTS. - Correlacionadas: Executadas por linha da externa, dependem dela (impactam performance).
CTEs (WITH): Clareza e Reusabilidade
CTEs (WITH) oferecem clareza e reusabilidade, superando subconsultas aninhadas. São resultados temporários e nomeados, definidos no escopo da instrução SQL.
Vantagens: legibilidade e reusabilidade em queries complexas, dividindo a lógica em blocos nomeados e referenciáveis.
Sintaxe Básica:
WITH NomeDaCTE AS (SELECT Coluna1 FROM TabelaOriginal), OutraCTE AS (SELECT ColunaA FROM NomeDaCTE) SELECT * FROM OutraCTE;
Vantagens das CTEs:
- Organização/Legibilidade: Modulariza o código para compreensão.
- Reusabilidade: Referenciável múltiplas vezes.
- Depuração: Isola e corrige problemas.
- Performance: Otimizadores podem ser mais eficientes (em casos específicos).
Exemplo Prático (CTE):
CTEs resolvem problemas complexos em etapas, ex: encontrar o segundo maior preço:
WITH MaxPreco AS (SELECT MAX(PrecoUnitario) FROM Produtos),
SegundoMaxPreco AS (SELECT MAX(PrecoUnitario) FROM Produtos WHERE PrecoUnitario < (SELECT * FROM MaxPreco))
SELECT NomeProduto, PrecoUnitario FROM Produtos WHERE PrecoUnitario = (SELECT * FROM SegundoMaxPreco);
Subqueries e CTEs permitem consultas sofisticadas. Sua complexidade, no entanto, pode impactar a performance; atenção à eficiência.
8. Otimização e Boas Práticas: Escrevendo SQL Eficiente
Em produção, a performance de consultas SQL é tão crucial quanto sua correção. Queries lentas degradam a experiência, aumentam tempo de resposta, consomem recursos e causam instabilidade. A otimização é essencial para um BD eficiente e escalável.
Índices são ferramentas poderosas para acelerar a recuperação. Mapeiam valores de colunas para linhas, permitindo ao SGBD localizar dados rapidamente, sem varrer a tabela. Melhora drasticamente SELECT com WHERE, JOIN e ORDER BY. Use CREATE INDEX nome ON Tabela (Coluna); (ex: CREATE INDEX idx_usuarios_email ON usuarios (email);) e DROP INDEX nome ON Tabela;. Embora consumam espaço e sobrecarga em INSERT/UPDATE/DELETE, seus benefícios em leitura são inestimáveis em sistemas de alta demanda.
Evite SELECT *. Em produção, selecione apenas as colunas necessárias, reduzindo tráfego de rede, memória e permitindo uso eficaz de índices. Prefira SELECT nome, email FROM usuarios; a SELECT * FROM usuarios;.
A otimização da cláusula WHERE é vital para a eficácia dos índices. Colunas indexadas não devem ser modificadas por funções (ex: WHERE YEAR(data_venda) = 2023 impede o índice). Use WHERE data_venda BETWEEN '2023-01-01' AND '2023-12-31' para mantê-las "limpas" (SARGable).
Para legibilidade e manutenção, use comentários no SQL. Eles explicam lógicas complexas ou o propósito da consulta, usando -- (linha única) ou /* seu comentário aqui */ (múltiplas linhas).
/* Esta consulta retorna usuários ativos de 2023. */
SELECT nome, email
FROM usuarios
WHERE status = 'ativo' AND data_cadastro BETWEEN '2023-01-01' AND '2023-12-31';
Verifique a eficácia das otimizações com EXPLAIN, que mostra o 'plano de execução' (busca dados, índices usados e ordem das operações). Ex: EXPLAIN SELECT * FROM produtos WHERE preco > 100;. Em PostgreSQL, EXPLAIN ANALYZE mostra tempos reais. Compreender o plano é essencial para identificar gargalos.
O desempenho varia entre SGBDs e ambientes (MySQL, PostgreSQL, SQL Server) devido a otimizadores e implementações distintas. Teste no ambiente de destino.
Parabéns! Você dominou os fundamentos de SQL eficiente.
9. Próximos Passos e Conclusão: Sua Jornada no SQL
Parabéns! Concluiu este guia, avançando em SQL. Cobrimos SELECT, DML, JOINs, agregação, subqueries, CTEs e otimização.
Maestria em SQL exige prática. A solidez vem ao resolver exercícios e desafios reais. Crie cenários, explore bancos e persista nos erros – parte do aprendizado.
Use documentação, cursos, desafios SQL (HackerRank, LeetCode) e comunidades.
Sua jornada SQL continua. Explore avançados: Stored Procedures, Views, Triggers, Funções de Janela. Aprofunde DDL (ALTER TABLE, DROP TABLE e CREATE TABLE), Normalização e Transações Avançadas (isolamento, SAVEPOINTs, concorrência).
SQL extrai insights para decisões informadas. Mantenha curiosidade, pratique e explore. Sua proficiência SQL será um diferencial inestimável.