Welington Pereira
Desenvolvedor Full Stack & Consultor
Especialista em linguagens de programação e banco de dados. Compartilhando dicas de programação práticas, tutoriais e soluções para o dia a dia do desenvolvedor.
Desenvolvedor Full Stack & Consultor
Especialista em linguagens de programação e banco de dados. Compartilhando dicas de programação práticas, tutoriais e soluções para o dia a dia do desenvolvedor.
## Tipos de JOIN
Vou explicar usando duas tabelas como exemplo:
- **CLIENTES** (id, nome)
- **PEDIDOS** (id, cliente_id, valor)
### 1. **INNER JOIN** (ou só JOIN)
**Retorna apenas os registros que têm correspondência em AMBAS as tabelas.**
```sql
SELECT * FROM CLIENTES c
INNER JOIN PEDIDOS p ON c.id = p.cliente_id;
**Resultado:** Só clientes que fizeram pedidos. Clientes sem pedido NÃO aparecem.
Cliente com pedido → aparece
Cliente sem pedido → não aparece
### 2. **LEFT JOIN** (ou LEFT OUTER JOIN)
**Retorna TODOS os registros da tabela da ESQUERDA + correspondências da direita.**
```sql
SELECT * FROM CLIENTES c
LEFT JOIN PEDIDOS p ON c.id = p.cliente_id;
**Resultado:** Todos os clientes. Quem não tem pedido fica com NULL nos campos de pedido.
Cliente com pedido → aparece com dados do pedido
Cliente sem pedido → aparece com NULL nos campos do pedido
### 3. **RIGHT JOIN** (ou RIGHT OUTER JOIN)
**Retorna TODOS os registros da tabela da DIREITA + correspondências da esquerda.**
```sql
SELECT * FROM CLIENTES c
RIGHT JOIN PEDIDOS p ON c.id = p.cliente_id;
**Resultado:** Todos os pedidos. Pedidos sem cliente (raro) aparecem com NULL nos campos de cliente.
Pedido com cliente → aparece com dados do cliente
Pedido sem cliente → aparece com NULL nos campos do cliente
### 4. **FULL JOIN** (ou FULL OUTER JOIN)
**Retorna TODOS os registros de AMBAS as tabelas.**
```sql
SELECT * FROM CLIENTES c
FULL JOIN PEDIDOS p ON c.id = p.cliente_id;
**Resultado:** Tudo. Clientes sem pedido e pedidos sem cliente aparecem com NULLs.
Clientes com e sem pedido → todos aparecem
Pedidos com e sem cliente → todos aparecem
### 5. **CROSS JOIN**
**Produto cartesiano: cada linha da primeira combina com TODAS da segunda.**
```sql
SELECT * FROM CLIENTES
CROSS JOIN PEDIDOS;
**Resultado:** Se 10 clientes e 100 pedidos → 1.000 registros (cada cliente com cada pedido)
### 6. **SELF JOIN**
**JOIN da tabela com ela mesma.** Útil para relações hierárquicas.
```sql
SELECT e.nome AS empregado, g.nome AS gerente
FROM FUNCIONARIOS e
LEFT JOIN FUNCIONARIOS g ON e.gerente_id = g.id;
## Resumo Visual
| Tipo | Esquerda | Direita |
| **INNER** | ✅ só correspondentes | ✅ só correspondentes |
| **LEFT** | ✅ todos | ✅ só correspondentes |
| **RIGHT** | ✅ só correspondentes | ✅ todos |
| **FULL** | ✅ todos | ✅ todos |
## Exemplo com diagrama mental
Tabela A Tabela B
┌─────┐ ┌─────┐
│ 1 │ │ 2 │
│ 2 │ │ 3 │
│ 3 │ │ 4 │
│ 5 │ │ │
└─────┘ └─────┘
INNER JOIN: [2, 3] (o que tem nos dois)
LEFT JOIN: [1, 2, 3, 5] (tudo de A)
RIGHT JOIN: [2, 3, 4] (tudo de B)
FULL JOIN: [1, 2, 3, 4, 5] (tudo de ambos)
```
## Dica prática
- **INNER JOIN**: quando só importam registros relacionados
- **LEFT JOIN**: quando não quer perder os registros da tabela principal (mais comum)
- **FULL JOIN**: quando precisa ver tudo de ambos os lados
- **RIGHT JOIN**: raro, dá pra substituir por LEFT trocando ordem das tabelas
## Diferença entre NOT LIKE e <>
São operadores completamente diferentes com propósitos distintos:
### **LIKE / NOT LIKE**
- Usado para **comparação de padrões** com strings
- Permite uso de curingas: `%` (qualquer sequência) e `_` (um caractere)
- Funciona **apenas com dados do tipo texto** (VARCHAR2, CHAR, etc.)
```sql
-- Exemplos com NOT LIKE
WHERE nome NOT LIKE 'João%' -- Não começa com "João"
WHERE nome NOT LIKE '%Silva%' -- Não contém "Silva"
WHERE nome NOT LIKE '_____' -- Não tem exatamente 5 caracteres
```
### **<> (ou !=)**
- Usado para **desigualdade exata**
- Compara valores completos
- Funciona com **qualquer tipo de dado** (números, datas, textos)
```sql
-- Exemplos com <>
WHERE id <> 10 -- id diferente de 10
WHERE nome <> 'João' -- nome exatamente diferente de 'João'
WHERE data <> SYSDATE -- data diferente de hoje
```
## Principais diferenças:
CARACTERÍSTICAS NOT LIKE <>
**Propósito** Comparação de padrão Desigualdade exata
**Curingas** Sim (%, _) Não
**Tipo de dado** Apenas texto Qualquer tipo
**NULL** Retorna NULL Retorna NULL
**Performance** Geralmente mais lento | Geralmente mais rápido
## Comportamento com NULL:
**Ambos retornam NULL quando comparados com NULL:**
```sql
-- Se campo é NULL:
WHERE campo NOT LIKE '%valor%' -- NULL (não retorna)
WHERE campo <> 'valor' -- NULL (não retorna)
-- Para incluir NULLs, é necessário tratar:
WHERE (campo IS NULL OR campo NOT LIKE '%valor%')
```
## Exemplo prático com seu caso:
```sql
-- NOT LIKE: exclui apenas padrões específicos
WHERE PAR_X_OPERADORPARC NOT LIKE 'PARCERIA - 05'
-- Exclui: 'PARCERIA - 05', 'PARCERIA - 05 algo', 'XPARCERIA - 05X'
-- <>: exclui apenas o valor exato
WHERE PAR_X_OPERADORPARC <> 'PARCERIA - 05'
-- Exclui APENAS: 'PARCERIA - 05' (exato, sem espaços extras)
-- Se o campo tem espaços, <> falha:
-- 'PARCERIA - 05 ' (com espaço) NÃO será excluído com <>
-- Mas será excluído com NOT LIKE 'PARCERIA - 05' (depende do padrão)
```
## Para seu cenário específico:
Se o problema é espaços em branco, considere:
```sql
-- NOT LIKE com tratamento de espaços
AND TRIM(PAR_X_OPERADORPARC) NOT LIKE 'PARCERIA - 05'
-- Ou com <> tratando espaços
AND TRIM(PAR_X_OPERADORPARC) <> 'PARCERIA - 05'
```
**Resumo:** Use `NOT LIKE` quando precisa de busca por padrão com curingas. Use `<>` para comparar valores exatos e em campos não-texto.