O Exemplo abaixo utiliza todos os recursos aprendidos recentemente em um cenário prático.
Este cenário é baseado num caso comum hoje em dia. Alguns bancos de dados consideram que todas as pessoas podem ser ao mesmo tempo CLIENTES, COMPRADORES e FORNECEDORES.
Na prática, nada impede que um cliente seja também um funcionário da empresa.
Por isso utiliza uma única tabela com informações de pessoas, denominada CONTATO. Essa tabela contém informações de todas as pessoas físicas possíveis para o sistema da empresa.
Nessa situação, como criar uma lista telefonica com o nome do todos os contatos, mas identificando quais são clientes e quais são Empregados ?
/* QUANTOS REGISTROS TEMOS NA TABELA DE EMPREGADOS */
select
count(*)
from contatos
/* RESULTADO: 19772 REGISTRO*/
/* QUEM SÃO OS EMPREGADOS */
/* O INNER JOIN VAI TRAZER APENAS OS CONTATOS QUE POSSUEM REGISTRO RELACIONADO NA TABELA DE EMPREGADOS*/
select c.*
from contatos c inner
join empregados e on c.contatoid = e.contatoid
/* RESULTADO: 290 REGISTRO*/
/*
PELA LÓGICA, BASTARIA ENTÃO SELECIONAR OS CONTATOS QUE NÃO SÃO IGUAIS.. MAS…
NÃO TENTEM ISSO EM CASA 🙂 */
select c.*
from contatos c inner
join empregados e on c.contatoid <> e.contatoid
/* RESULTADO: 5.170.590 REGISTROS !!! MAS O TOTAL DA TABELA NÃO É DE APENAS 19.972 ? */
/* É DIFICIL DE EXPLICAR AQUI O MOTIVO.. MAS BASTA SABER QUE NAO DÁ MUITO CERTO */
/* ENTÃO PRECISAMOS DE UMA ABORDAGEM DIFERENTE, QUE TAL ELIMINAR DA LISTA ÀQUELES QUE JÁ CONHECEMOS QUEM SÃO.. OS FUNCIONÁRIOS*/
SELECT Nome, SobreNome, Fone, Tipo =
‘Cliente’
FROM Contatos WHERE ContatoID not
in
(
select c.contatoID from contatos c inner
join empregados e on c.contatoid = e.contatoid
)
/* RESULTADO: 19682 REGISTROS (APENAS CLIENTES) */
/*Agora, vamos unir os rsultados e gerar uma tabela única de clientes e empregados*/
SELECT c.*
FROM contatos c inner
join empregados e
on c.contatoid = e.contatoid
UNION — UNE O RESULTADO DAS DUAS CONSULTAS
SELECT Nome, SobreNome, Fone, Tipo =
‘Cliente’
FROM Contatos WHERE ContatoID not
in
(
select c.contatoID from contatos c inner
join empregados e on c.contatoid = e.contatoid
)
ORDER
BY 1,2 — ORDER BY SÓ PODE APARECER NA ULTIMA QUERY