-- SELECIONE o nome dos artistas
SELECT artista_nome
-- DA tabela artistas
FROM artistas
-- ONDE o gênero seja MPB
WHERE artista_genero = 'MPB';Quais clientes não compram há mais de seis meses? Marketing precisa da lista para a campanha de reativação.
Quais artistas tiveram crescimento de receita nos últimos 12 meses? Curadoria precisa renovar contratos.
Quais países têm o maior ticket médio? Expansão precisa definir mercados prioritários.
SQL é quase português. Uma query pode ser lida em voz alta e compreendida por quem nunca programou — o ponto é esse.
SELECT · FROM · WHERE · JOIN · GROUP BY resolvem 80% das perguntas analíticas de uma empresa. Os outros 20% são variações.
A IA pode gerar código correto que responde a pergunta errada. A curadoria analítica ainda é humana.
Anomalias de inserção, alteração e exclusão. Ana Lima com dois IDs. Preço zerado em 4 linhas.
Cada entidade em sua tabela. PKs e FKs garantem integridade. Preço centralizado em faixas.
CREATE TABLE clientes (
cliente_id SERIAL PRIMARY KEY,
cliente_nome VARCHAR(100) NOT NULL,
cliente_email VARCHAR(100) UNIQUE NOT NULL,
cliente_pais VARCHAR(50),
cliente_cidade VARCHAR(50)
);
CREATE TABLE artistas (
artista_id SERIAL PRIMARY KEY,
artista_nome VARCHAR(100) NOT NULL,
artista_genero VARCHAR(50),
artista_pais_origem VARCHAR(50)
);
CREATE TABLE gravadoras (
gravadora_id SERIAL PRIMARY KEY,
gravadora_nome VARCHAR(100) NOT NULL
);
CREATE TABLE albuns (
album_id SERIAL PRIMARY KEY,
album_titulo VARCHAR(150) NOT NULL,
album_ano SMALLINT,
artista_id INTEGER REFERENCES artistas(artista_id),
gravadora_id INTEGER REFERENCES gravadoras(gravadora_id)
);
CREATE TABLE faixas (
faixa_id SERIAL PRIMARY KEY,
faixa_titulo VARCHAR(200) NOT NULL,
faixa_duracao_seg INTEGER,
faixa_preco_usd NUMERIC(6,2) NOT NULL,
faixa_formato VARCHAR(10),
album_id INTEGER REFERENCES albuns(album_id)
);
CREATE TABLE pedidos (
pedido_id SERIAL PRIMARY KEY,
pedido_data DATE NOT NULL,
cliente_id INTEGER REFERENCES clientes(cliente_id)
);
CREATE TABLE itens_pedido (
pedido_id INTEGER REFERENCES pedidos(pedido_id),
faixa_id INTEGER REFERENCES faixas(faixa_id),
qtd_comprada INTEGER DEFAULT 1,
total_item_usd NUMERIC(6,2),
PRIMARY KEY (pedido_id, faixa_id)
);SELECT cliente_nome, cliente_email, cliente_pais
FROM clientes;| cliente_nome | cliente_email | cliente_pais |
|---|---|---|
| Carlos Mendes | carlos@email.com | Brasil |
| Julia Ferreira | julia@email.com | Brasil |
| Emma Clarke | emma@email.com | UK |
| Yuki Tanaka | yuki@email.com | Japão |
| … | … | … |
SELECT faixa_titulo, faixa_preco_usd, faixa_formato
FROM faixas
ORDER BY faixa_preco_usd DESC;| faixa_titulo | faixa_preco_usd | faixa_formato |
|---|---|---|
| Milonga Infinita | 4.99 | MP3 |
| Nacht Signal | 4.49 | FLAC |
| Saudade Eterna | 3.99 | MP3 |
| Foggy Days | 3.99 | AAC |
| Teranga | 1.99 | MP3 |
| … | … | … |
ASC (padrão, crescente) ou DESC (decrescente).SELECT faixa_preco_usd AS preco renomeia a coluna no resultado, útil para relatórios mais legíveis.SELECT cliente_nome, cliente_email
FROM clientes
WHERE cliente_pais = 'Brasil';SELECT p.pedido_id,
p.pedido_data,
c.cliente_nome,
c.cliente_pais,
ip.total_item_usd
FROM pedidos p
JOIN clientes c ON p.cliente_id = c.cliente_id
JOIN itens_pedido ip ON p.pedido_id = ip.pedido_id
WHERE p.pedido_data >= '2024-03-01'
ORDER BY p.pedido_data;SELECT c.cliente_nome,
c.cliente_email,
MAX(p.pedido_data) AS ultima_compra
FROM clientes c
LEFT JOIN pedidos p ON c.cliente_id = p.cliente_id
GROUP BY c.cliente_id, c.cliente_nome, c.cliente_email
HAVING MAX(p.pedido_data) < CURRENT_DATE - INTERVAL '180 days'
OR MAX(p.pedido_data) IS NULL
ORDER BY ultima_compra ASC;SELECT c.cliente_pais,
COUNT(DISTINCT p.pedido_id) AS total_pedidos,
ROUND(SUM(ip.total_item_usd), 2) AS receita_total,
ROUND(AVG(ip.total_item_usd), 2) AS ticket_medio
FROM clientes c
JOIN pedidos p ON c.cliente_id = p.cliente_id
JOIN itens_pedido ip ON p.pedido_id = ip.pedido_id
WHERE c.cliente_pais IS NOT NULL
GROUP BY c.cliente_pais
ORDER BY ticket_medio DESC;| cliente_pais | total_pedidos | receita_total | ticket_medio |
|---|---|---|---|
| Japão | 3 | 17.94 | 5.98 |
| Alemanha | 2 | 11.46 | 5.73 |
| Argentina | 2 | 9.98 | 4.99 |
| Brasil | 18 | 57.84 | 3.21 |
HAVING COUNT(*) > 5Tenho um banco PostgreSQL com as tabelas:
- clientes (cliente_id, cliente_nome, cliente_pais)
- pedidos (pedido_id, cliente_id, pedido_data)
- itens_pedido (pedido_id, faixa_id, total_item_usd)
Escreva uma query que retorne os 5 países com maior
ticket médio por pedido, excluindo clientes sem país
cadastrado. Ordene do maior para o menor.-- Pergunta: Quais os artistas com maior receita em 2024?
-- Esta query tem 3 erros. Use a IA para encontrá-los.
SELECT ar.Name AS artista,
SUM(il.UnitPrice * il.Quantity) AS receita
FROM Artist ar
JOIN Album al ON ar.ArtistId = al.ArtistId
JOIN Track t ON al.AlbumId = t.AlbumId
JOIN InvoiceLine il ON t.TrackId = il.TrackId
WHERE il.InvoiceDate > '2024-01-01' -- Erro 1
GROUP BY ar.Name
ORDERED BY receita DESC -- Erro 2
LIMIT 10; -- Erro 3 (lógico)InvoiceDate pertence à tabela Invoice, não a InvoiceLine. Falta o JOIN com Invoice na query.ORDERED BY não existe em SQL. O comando correto é ORDER BY. O banco retorna erro imediatamente.Chinook_Sqlite.sql fornecido pelo professor. O banco será carregado automaticamente com 11 tabelas e dados reais.Artist → Album → Track → InvoiceLine · Função: SUM(UnitPrice * Quantity) · Ordenar: DESCCustomer → Invoice · Função: AVG(Total) agrupado por Country · Excluir países com NULLCustomer → Invoice · Condição: MAX(InvoiceDate) < '2014-01-01' com HAVING · Ordenar pela data mais antigaCustomer → Invoice → InvoiceLine → Track → Album → Artist · Agrupe por Country e ArtistId · Use subquery ou CTE para pegar o top 1 por paísSELECT ar.Name AS artista,
ROUND(SUM(il.UnitPrice * il.Quantity), 2) AS receita
FROM Artist ar
JOIN Album al ON ar.ArtistId = al.ArtistId
JOIN Track t ON al.AlbumId = t.AlbumId
JOIN InvoiceLine il ON t.TrackId = il.TrackId
GROUP BY ar.ArtistId, ar.Name
ORDER BY receita DESC
LIMIT 10;