---
# System prepended metadata

title: "\U0001F4D8 SQL para Concursos — Banca FCC"

---

# 📘 SQL para Concursos — Banca FCC

> Resumo completo com foco nas questões da FCC: ordem de execução, cláusulas, funções, joins, subqueries e pegadinhas clássicas.

---

## 1. ESTRUTURA GERAL DE UMA QUERY SELECT

```sql
SELECT   [colunas / expressões / funções de agregação]
FROM     [tabela(s)]
JOIN     [tabela] ON [condição]
WHERE    [filtro de linhas]
GROUP BY [colunas de agrupamento]
HAVING   [filtro sobre grupos]
ORDER BY [colunas de ordenação]
LIMIT    [quantidade de linhas]  -- nem sempre cobrado
```

---

## 2. ORDEM DE EXECUÇÃO (LÓGICA) ⚠️ CUIDADO NAS PROVAS

A FCC cobra bastante a **ordem em que o banco de dados processa** as cláusulas — que é **diferente** da ordem em que escrevemos.

| Passo | Cláusula       | O que faz                                    |
|-------|----------------|----------------------------------------------|
| 1     | `FROM`         | Define as tabelas (e produto cartesiano)      |
| 2     | `JOIN`         | Aplica os joins                               |
| 3     | `WHERE`        | Filtra as linhas (antes do agrupamento)       |
| 4     | `GROUP BY`     | Agrupa as linhas                              |
| 5     | `HAVING`       | Filtra os grupos (depois do agrupamento)      |
| 6     | `SELECT`       | Seleciona / calcula as colunas               |
| 7     | `DISTINCT`     | Remove duplicatas                             |
| 8     | `ORDER BY`     | Ordena o resultado                            |
| 9     | `LIMIT/OFFSET` | Limita a quantidade de linhas retornadas      |

![image](https://hackmd.io/_uploads/rkKLsNbp-g.png)

> **Pegadinha clássica FCC:** `WHERE` **não pode usar** alias definidos no `SELECT` nem funções de agregação (`SUM`, `COUNT`, etc.), pois o `WHERE` é executado **antes** do `SELECT`. Use `HAVING` para filtrar agregações.

---


## 3. DIFERENÇA ENTRE WHERE e HAVING

| Característica         | WHERE                        | HAVING                         |
|------------------------|------------------------------|-------------------------------|
| Momento de execução    | Antes do GROUP BY            | Depois do GROUP BY            |
| Filtra                 | Linhas individuais           | Grupos                        |
| Pode usar agregação?   | ❌ Não                        | ✅ Sim                        |
| Pode usar sem GROUP BY?| ✅ Sim                        | ✅ Sim (filtra resultado total)|

```sql
-- ✅ CORRETO
SELECT departamento, COUNT(*) AS total
FROM funcionarios
WHERE salario > 1000          -- filtra linhas antes de agrupar
GROUP BY departamento
HAVING COUNT(*) > 5;          -- filtra grupos após agrupar

-- ❌ ERRADO — FCC adora essa pegadinha!
SELECT departamento, COUNT(*) AS total
FROM funcionarios
WHERE COUNT(*) > 5            -- ERRO: não pode usar agregação no WHERE
GROUP BY departamento;
```

---

## 4. FUNÇÕES DE AGREGAÇÃO

| Função        | Descrição                                      |
|---------------|------------------------------------------------|
| `COUNT(*)`    | Conta todas as linhas (incluindo NULLs)        |
| `COUNT(col)`  | Conta linhas onde col **não é NULL**           |
| `SUM(col)`    | Soma os valores (ignora NULL)                  |
| `AVG(col)`    | Média dos valores (ignora NULL)                |
| `MAX(col)`    | Maior valor                                    |
| `MIN(col)`    | Menor valor                                    |

> **Atenção:** `COUNT(*)` ≠ `COUNT(coluna)`. Se a coluna tiver NULLs, `COUNT(coluna)` retornará menos.

---

## 5. TIPOS DE JOIN

```
Tabela A          Tabela B
  [  A ∩ B  ]
```

| JOIN            | Retorna                                                    |
|-----------------|------------------------------------------------------------|
| `INNER JOIN`    | Apenas linhas com correspondência em **ambas** as tabelas  |
| `LEFT JOIN`     | Todas de A + correspondências de B (B sem match = NULL)   |
| `RIGHT JOIN`    | Todas de B + correspondências de A (A sem match = NULL)   |
| `FULL OUTER JOIN`| Todas de A e B (sem match = NULL em qualquer lado)       |
| `CROSS JOIN`    | Produto cartesiano (todas as combinações)                  |
| `SELF JOIN`     | Join da tabela com ela mesma (usa alias)                   |

```sql
-- INNER JOIN
SELECT e.nome, d.nome AS departamento
FROM empregado e
INNER JOIN departamento d ON e.dep_id = d.id;

-- LEFT JOIN — inclui empregados SEM departamento
SELECT e.nome, d.nome AS departamento
FROM empregado e
LEFT JOIN departamento d ON e.dep_id = d.id;

-- SELF JOIN — encontrar funcionário e seu gerente
SELECT e.nome AS funcionario, g.nome AS gerente
FROM funcionario e
JOIN funcionario g ON e.gerente_id = g.id;
```

![image](https://hackmd.io/_uploads/SypOiE-pWl.png)


> **FCC cobra:** qual join retorna linhas sem correspondência e de qual lado.

---

## 6. SUBQUERIES (SUBCONSULTAS)

### 6.1 No WHERE
```sql
-- Funcionários que ganham mais que a média
SELECT nome FROM funcionario
WHERE salario > (SELECT AVG(salario) FROM funcionario);
```

### 6.2 Correlacionadas
A subquery referencia a query externa — executada **uma vez por linha** da query principal.
```sql
SELECT nome FROM funcionario f
WHERE salario > (
    SELECT AVG(salario) FROM funcionario
    WHERE departamento_id = f.departamento_id
);
```

### 6.3 EXISTS / NOT EXISTS
```sql
-- Departamentos que têm pelo menos 1 funcionário
SELECT nome FROM departamento d
WHERE EXISTS (
    SELECT 1 FROM funcionario WHERE departamento_id = d.id
);
```

### 6.4 IN / NOT IN
```sql
SELECT nome FROM funcionario
WHERE departamento_id IN (SELECT id FROM departamento WHERE cidade = 'SP');
```

> **Pegadinha FCC com NOT IN e NULL:** Se a subquery retornar algum NULL, `NOT IN` retorna **vazio**! Use `NOT EXISTS` para segurança.

---

## 7. OPERADORES DE CONJUNTO

| Operador      | Descrição                                                   |
|---------------|-------------------------------------------------------------|
| `UNION`       | Une resultados, **remove duplicatas**                       |
| `UNION ALL`   | Une resultados, **mantém duplicatas** (mais rápido)        |
| `INTERSECT`   | Retorna apenas linhas presentes nas **duas** consultas      |
| `EXCEPT`      | Retorna linhas da 1ª consulta que **não estão** na 2ª      |

> **Regras obrigatórias:** Mesmo número de colunas e tipos compatíveis em cada posição.

---

## 8. FUNÇÕES DE STRING (mais cobradas pela FCC)

| Função                         | Descrição                              | Exemplo                            |
|--------------------------------|----------------------------------------|------------------------------------|
| `UPPER(str)`                   | Converte para maiúsculas               | `UPPER('sql')` → `'SQL'`           |
| `LOWER(str)`                   | Converte para minúsculas               | `LOWER('SQL')` → `'sql'`           |
| `LENGTH(str)` / `LEN(str)`    | Comprimento da string                  | `LENGTH('abc')` → `3`              |
| `SUBSTRING(str, pos, len)`     | Extrai parte da string                 | `SUBSTRING('abcde', 2, 3)` → `'bcd'`|
| `TRIM(str)`                    | Remove espaços dos dois lados          | `TRIM('  x  ')` → `'x'`           |
| `LTRIM` / `RTRIM`              | Remove espaços da esquerda/direita     |                                    |
| `CONCAT(a, b)`                 | Concatena strings                      | `CONCAT('a','b')` → `'ab'`         |
| `REPLACE(str, old, new)`       | Substitui substring                    |                                    |
| `LIKE`                         | Comparação com padrão                  | `LIKE 'A%'` (começa com A)         |

**Wildcards do LIKE:**
- `%` → qualquer sequência de caracteres (inclusive vazia)
- `_` → exatamente **um** caractere qualquer

---

## 9. FUNÇÕES NUMÉRICAS

| Função           | Descrição                        |
|------------------|----------------------------------|
| `ROUND(n, d)`    | Arredonda n com d casas decimais |
| `FLOOR(n)`       | Arredonda para baixo             |
| `CEILING(n)`     | Arredonda para cima              |
| `ABS(n)`         | Valor absoluto                   |
| `MOD(a, b)`      | Resto da divisão                 |
| `POWER(a, b)`    | a elevado a b                    |

---

## 10. FUNÇÕES DE DATA

| Função                        | Descrição                           |
|-------------------------------|-------------------------------------|
| `CURRENT_DATE`                | Data atual                          |
| `CURRENT_TIMESTAMP` / `NOW()` | Data e hora atual                   |
| `EXTRACT(parte FROM data)`    | Extrai ano, mês, dia, hora...       |
| `DATEDIFF(d1, d2)`            | Diferença entre datas (dias)        |
| `DATE_ADD(data, INTERVAL n)` | Adiciona intervalo à data           |

```sql
SELECT EXTRACT(YEAR FROM data_admissao) AS ano FROM funcionario;
```

---

## 11. NULL — COMPORTAMENTO ESPECIAL ⚠️

- Qualquer operação aritmética com NULL resulta em **NULL**
- Qualquer comparação com NULL resulta em **NULL** (não TRUE, não FALSE)
- Use `IS NULL` e `IS NOT NULL` para verificar
- `NULL = NULL` → **FALSE** (ou NULL, dependendo do contexto)
- `COALESCE(a, b, c)` → retorna o **primeiro valor não-NULL**
- `NULLIF(a, b)` → retorna NULL se a = b, senão retorna a

```sql
-- ❌ ERRADO
WHERE salario = NULL

-- ✅ CORRETO
WHERE salario IS NULL

-- COALESCE
SELECT COALESCE(comissao, 0) FROM funcionario; -- substitui NULL por 0
```

---

## 12. DDL — COMANDOS DE DEFINIÇÃO

| Comando          | Descrição                          |
|------------------|------------------------------------|
| `CREATE TABLE`   | Cria tabela                        |
| `ALTER TABLE`    | Altera estrutura da tabela         |
| `DROP TABLE`     | Remove tabela e seus dados         |
| `TRUNCATE TABLE` | Remove **todos os dados** da tabela (mais rápido que DELETE sem WHERE) |
| `CREATE INDEX`   | Cria índice                        |
| `CREATE VIEW`    | Cria visão                         |

```sql
CREATE TABLE produto (
    id       INT PRIMARY KEY,
    nome     VARCHAR(100) NOT NULL,
    preco    DECIMAL(10,2),
    cat_id   INT REFERENCES categoria(id)  -- FK
);

ALTER TABLE produto ADD COLUMN estoque INT DEFAULT 0;
ALTER TABLE produto DROP COLUMN estoque;
```

---

## 13. DML — COMANDOS DE MANIPULAÇÃO

```sql
-- INSERT
INSERT INTO produto (id, nome, preco) VALUES (1, 'Caneta', 2.50);

-- UPDATE
UPDATE produto SET preco = 3.00 WHERE id = 1;

-- DELETE
DELETE FROM produto WHERE id = 1;

-- TRUNCATE (sem WHERE, não pode ter rollback em alguns SGBDs)
TRUNCATE TABLE produto;
```

> **Diferença DELETE vs TRUNCATE:**
> - `DELETE` pode ter `WHERE`, pode fazer rollback, dispara triggers
> - `TRUNCATE` remove tudo, geralmente mais rápido, pode não disparar triggers

---

## 14. DCL — CONTROLE DE ACESSO

```sql
GRANT  SELECT, INSERT ON produto TO usuario1;
REVOKE INSERT ON produto FROM usuario1;
```

---

## 15. TCL — CONTROLE DE TRANSAÇÕES

```sql
BEGIN;           -- inicia transação
COMMIT;          -- confirma alterações
ROLLBACK;        -- desfaz alterações
SAVEPOINT sp1;   -- cria ponto de salvamento
ROLLBACK TO sp1; -- volta ao savepoint
```

### Propriedades ACID
| Propriedade   | Descrição                                                  |
|---------------|------------------------------------------------------------|
| **A**tomicity | A transação é tudo ou nada                                 |
| **C**onsistency | O banco vai de um estado válido para outro válido        |
| **I**solation | Transações concorrentes não interferem entre si            |
| **D**urability | Após COMMIT, as mudanças persistem mesmo com falha       |

---

## 16. CONSTRAINTS (RESTRIÇÕES)

| Constraint      | Descrição                                            |
|-----------------|------------------------------------------------------|
| `PRIMARY KEY`   | Identifica unicamente cada linha (NOT NULL + UNIQUE) |
| `FOREIGN KEY`   | Referencia PK de outra tabela                        |
| `UNIQUE`        | Valores únicos (permite NULL, depende do SGBD)       |
| `NOT NULL`      | Não permite valor nulo                               |
| `CHECK`         | Valida condição                                      |
| `DEFAULT`       | Valor padrão quando não informado                    |

---

## 17. VIEWS (VISÕES)

```sql
CREATE VIEW vw_funcionarios_sp AS
SELECT nome, salario FROM funcionario WHERE cidade = 'SP';

-- Consultar a view como se fosse tabela
SELECT * FROM vw_funcionarios_sp;

DROP VIEW vw_funcionarios_sp;
```

> **FCC cobra:** Views são consultas armazenadas, **não armazenam dados físicos** (exceto materialized views). Simplificam consultas complexas e podem restringir acesso.

---

## 18. ÍNDICES

```sql
CREATE INDEX idx_func_nome ON funcionario(nome);
CREATE UNIQUE INDEX idx_func_cpf ON funcionario(cpf);
DROP INDEX idx_func_nome;
```

> Índices **aceleram leituras** (`SELECT`) mas **penalizam escritas** (`INSERT`, `UPDATE`, `DELETE`). A PRIMARY KEY cria índice automaticamente.

---

## 19. DISTINCT e GROUP BY — DIFERENÇAS

```sql
-- DISTINCT: remove linhas duplicadas no resultado final
SELECT DISTINCT departamento FROM funcionario;

-- GROUP BY: agrupa para usar funções de agregação
SELECT departamento, COUNT(*) FROM funcionario GROUP BY departamento;
```

> `GROUP BY` sem função de agregação se comporta de forma semelhante ao `DISTINCT`, mas são conceitualmente diferentes.

---

## 20. ORDER BY

```sql
SELECT nome, salario FROM funcionario
ORDER BY salario DESC, nome ASC;

-- Pode usar número da coluna (FCC adora cobrar isso)
ORDER BY 2 DESC, 1 ASC;  -- equivalente ao anterior
```

- `ASC` → crescente (padrão, pode omitir)
- `DESC` → decrescente
- NULL: comportamento varia por SGBD (geralmente vai para o final no ASC)

---

## 21. CASE WHEN

```sql
SELECT nome,
    CASE
        WHEN salario < 2000 THEN 'Baixo'
        WHEN salario < 5000 THEN 'Médio'
        ELSE 'Alto'
    END AS faixa_salarial
FROM funcionario;
```

---

## 22. PEGADINHAS CLÁSSICAS DA FCC ⚠️

1. **`WHERE` com agregação** → ERRO. Use `HAVING`.
2. **`NOT IN` com NULL na subquery** → retorna zero linhas.
3. **`COUNT(*)` vs `COUNT(coluna)`** → NULL é ignorado no segundo.
4. **Alias do SELECT não pode ser usado no WHERE** (mas pode no ORDER BY em alguns SGBDs).
5. **`UNION` remove duplicatas, `UNION ALL` não** → impacto na performance.
6. **`DELETE` sem WHERE** apaga tudo mas é diferente de `TRUNCATE`.
7. **`NULL = NULL` é FALSE** → sempre use `IS NULL`.
8. **`BETWEEN a AND b`** → inclusivo nos dois extremos.
9. **`LIKE '%texto%'`** → não usa índice, lento em tabelas grandes.
10. **Produto cartesiano sem JOIN condition** → `FROM A, B` sem WHERE gera todas as combinações.

---

## 23. EXEMPLOS DE QUESTÕES FCC — PADRÃO

### Questão tipo: "Qual o resultado da query?"
```sql
SELECT d.nome, COUNT(f.id) AS qtd
FROM departamento d
LEFT JOIN funcionario f ON f.dep_id = d.id
GROUP BY d.nome
HAVING COUNT(f.id) >= 2
ORDER BY qtd DESC;
```
> Retorna departamentos com **2 ou mais** funcionários, ordenados do maior para o menor. Departamentos sem funcionários **não** aparecem (por causa do HAVING filtrando COUNT = 0).

---

### Questão tipo: "Qual cláusula está incorreta?"
```sql
SELECT departamento, AVG(salario)
FROM funcionario
WHERE AVG(salario) > 3000   -- ❌ ERRADO
GROUP BY departamento;
```
> Deve substituir `WHERE` por `HAVING`.

---

*Resumo elaborado com foco nas cobranças recorrentes da banca FCC em concursos públicos de TI e áreas afins.*

**EXTRA**


Trabalhando com datas em 3 diferentes bancos de dado.

![17767263687804260213628430476498](https://hackmd.io/_uploads/HyQsWV4pbe.jpg)

Sintaxe do 