🔗 CAPÍTULO 15: LÓGICA NULL, SUBQUERIES E JOINS
No mundo real corporativo, os dados nunca estão em uma única tabela. Eles estão espalhados por dezenas de tabelas normalizadas. O desenvolvedor sênior é aquele capaz de "costurar" essas informações em tempo real. 🛡️🧩
🎯 Objetivo Curricular
Dominar a lógica ternária do valor NULL, compreender o escopo de Subqueries e construir painéis complexos cruzando dados através de INNER, LEFT, RIGHT e FULL JOIN.
🏢 O Cenário Prático (Seu Desafio)
A equipe de faturamento da TecProExpress fez uma busca simples para somar todos os pacotes entregues, mas o valor bateu milhares de reais a menos do que o real. Por quê? Porque alguns pacotes ainda não tinham um Motorista designado (ID_Motorista = NULL), e o JOIN que o desenvolvedor júnior usou simplesmente deletou esses pacotes do relatório!
"Seu desafio é dominar as armadilhas do
NULLe aplicar o tipo correto deJOINpara garantir que pacotes não atribuídos continuem aparecendo no faturamento geral."
🧠 Fundamentos: O Buraco Negro do NULL
No SQL, a lógica não é Binária (True/False). É Ternária (True/False/Unknown).
O NULL representa o "Desconhecido". E a regra de ouro é: A matemática com o desconhecido sempre resulta em desconhecido.
10 + NULL = NULL'A' = NULL->FALSO(Nem o NULL é igual a outro NULL!)
🛠️ Como checar se algo é NULL?
Você não pode usar = (igual). Você deve usar a palavra IS.
-- Errado (Não retorna nada)
SELECT * FROM pacote WHERE id_motorista = NULL;
-- Certo (Traz os pacotes sem motorista)
SELECT * FROM pacote WHERE id_motorista IS NULL;
📖 Subqueries (A Consulta Inception)
Uma Subquery é um SELECT dentro de outro SELECT. Usamos isso quando precisamos do resultado de uma busca para poder fazer outra busca.
🛠️ Código do Exemplo (Quem ganha mais que a média?)
-- A Subquery (entre parênteses) roda PRIMEIRO e calcula a média.
-- O valor calculado é passado para o SELECT de fora.
SELECT nome, salario
FROM motorista
WHERE salario > (SELECT AVG(salario) FROM motorista);
🔗 A Arte dos JOINs
Quando as tabelas foram normalizadas (Cap. 10), elas foram separadas. O JOIN é a "Supercola" que une elas de volta.
📊 Diagrama de Venn dos JOINs
flowchart LR
subgraph INNER JOIN
A1(("Tabela A")) --- B1(("Tabela B"))
end
subgraph LEFT JOIN
A2((("Tabela A"))) --- B2(("Tabela B"))
end
style A1 fill:#e0e0e0
style B1 fill:#e0e0e0
style A2 fill:#4caf50
style B2 fill:#e0e0e0
1. INNER JOIN (A Interseção Perfeita)
Retorna APENAS o que existe dos dois lados. (O erro do júnior da TecProExpress).
- Se o pacote não tem motorista, ele não aparece.
2. LEFT JOIN (Preservando a Tabela da Esquerda)
Retorna TUDO da Tabela A (Esquerda), mesmo que ela não tenha correspondência na Tabela B. (A solução para o relatório!).
- Todos os pacotes aparecem. Se não tiver motorista, a coluna do motorista vem preenchida com
NULL.
🛠️ Prática Obrigatória: Salvando o Faturamento
Cenário: Corrigindo o erro do painel da TecProExpress.
- Crie a tabela
motoristae a tabelapacote. - Insira dois pacotes com motoristas e um pacote com
id_motorista = NULL. - Crie uma query que liste todos os pacotes, mostrando o nome do motorista apenas quando ele existir.
🚀 Script de Seed (Gabarito de JOINs)
-- DDL
CREATE TABLE motorista (id INT PRIMARY KEY, nome VARCHAR(50));
CREATE TABLE pacote (id INT PRIMARY KEY, descricao VARCHAR(50), valor DECIMAL(10,2), id_motorista INT);
-- DML
INSERT INTO motorista VALUES (1, 'Carlos'), (2, 'Ana');
INSERT INTO pacote VALUES (100, 'Geladeira', 200.00, 1);
INSERT INTO pacote VALUES (101, 'TV', 50.00, 2);
INSERT INTO pacote VALUES (102, 'Micro-ondas', 30.00, NULL); -- Pacote sem dono
-- O ERRO DO JÚNIOR (O Micro-ondas não aparece)
-- SELECT p.descricao, m.nome FROM pacote p INNER JOIN motorista m ON p.id_motorista = m.id;
-- DQL (A SOLUÇÃO COM LEFT JOIN)
SELECT p.descricao, p.valor, m.nome AS motorista_responsavel
FROM pacote p
LEFT JOIN motorista m ON p.id_motorista = m.id;
🔍 Detalhamento da Consulta:
pacote p: A letrapé um Alias (Apelido), para não precisarmos digitar o nome completo da tabela toda hora.LEFT JOIN: Opacoteé a Tabela A (Esquerda, citada antes do JOIN). Logo, a query promete: "Mostrarei todos os pacotes, custe o que custar!".
📤 Instruções de Entrega (Microsoft Teams)
Após validar seus códigos práticos e de estudo:
Use o operador e para critérios rigorosos e ou para critérios flexíveis. Salve os arquivos com a extensão .sql (Ex: Atividade_XX_SeuNome.sql ou Atividade_XX_SeuNome.png ou Atividade_XX_SeuNome.drawio
💡 Checkpoint de Lógica
[!IMPORTANT] Dica do Especialista: Você quer se destacar na engenharia de dados? Entenda que
JOINssão operações matemáticas pesadas (Produto Cartesiano + Filtro). Em relatórios que cruzam 15 tabelas com milhões de linhas, a ordem que você escreve seusINNER JOINeLEFT JOINpode fazer a diferença entre a consulta terminar em 2 segundos ou travar o servidor da empresa. 🧠🛡️