Fundamentos de SQL

SQL é a linguagem que você usa para consultar, inserir e alterar dados em um banco de dados. Este guia começa pela ordem em que um comando SELECT é processado e segue, passo a passo, por funções e GROUP BY, junções, subconsultas, funções de janela e consultas hierárquicas, até chegar aos comandos que alteram os dados e confirmam essas alterações. Os exemplos usam sempre as mesmas tabelas de funcionários e departamentos, e cada capítulo tem uma figura que você pode manipular. A explicação toma o Oracle como base e aponta à parte os pontos em que o SQL Server se comporta de outro jeito. A forma de dividir e projetar as tabelas é assunto do guia Modelagem de dados.

01

Bancos de dados relacionais e o básico do SELECT

O vocabulário do banco de dados relacional

Um banco de dados relacional guarda os dados em tabelas (quadros de linhas e colunas) e liga uma tabela à outra por valores de chave. A teoria chama as mesmas coisas por outros nomes, então vale a pena conhecer os pares.

Teoria (modelo relacional)Na tabelaO que é
RelaçãoTabelaUm conjunto de linhas com a mesma estrutura
TuplaLinhaUma instância
AtributoColunaUma propriedade
Grau (degree)Número de colunasQuantidade de atributos
Cardinalidade (cardinality)Número de linhasQuantidade de tuplas
DomínioFaixa de valores da colunaO conjunto de valores que um atributo pode assumir

Uma relação tem algumas propriedades: não pode haver duas tuplas idênticas, não existe ordem entre as tuplas nem entre os atributos, e todo valor é atômico, ou seja, não dá para dividi-lo em partes menores.

As chaves também se dividem em tipos.

ChaveCondição
SuperchaveSó unicidade — qualquer combinação de colunas que identifique uma linha
Chave candidataUnicidade + minimalidade — candidata a virar chave primária
Chave primária (PK)A chave candidata escolhida como representante. Não aceita NULL nem repetição
Chave alternativaAs chaves candidatas que não foram escolhidas como chave primária
Chave estrangeira (FK)Uma coluna que referencia a chave primária de outra tabela

As regras que mantêm os dados sempre corretos são as restrições de integridade. As principais são a integridade de entidade (a chave primária não pode ser NULL nem se repetir), a integridade referencial (o valor de uma chave estrangeira precisa existir na tabela referenciada ou ser NULL) e a integridade de domínio (o valor de uma coluna precisa estar dentro do domínio definido).

As operações teóricas de um banco de dados relacional formam a álgebra relacional. Veja a que operação cada parte do SQL corresponde.

TipoOperaçãoSímboloNo SQL
Operadores relacionais purosSELECT (seleção)σWHERE — escolhe as linhas que atendem à condição
PROJECT (projeção)πLista do SELECT — escolhe as colunas que você quer
JOIN (junção)⋈JOIN — junta duas relações por um valor em comum
DIVISION (divisão)÷Mantém só as linhas que têm todos os valores do divisor (não há sintaxe equivalente direta)
Operadores de conjunto tradicionaisUnião / interseção / diferença∪ / ∩ / −UNION / INTERSECT / MINUS (EXCEPT)
Produto cartesiano×CROSS JOIN

Os quatro tipos de comando SQL

TipoComandosO que faz
DML (manipulação)SELECT, INSERT, UPDATE, DELETE, MERGEConsulta, insere, altera e exclui dados. Às vezes o SELECT sozinho é chamado de DQL
DDL (definição)CREATE, ALTER, DROP, RENAME, TRUNCATECria, altera e remove estruturas como tabelas
DCL (controle)GRANT, REVOKEConcede e revoga privilégios
TCL (controle de transação)COMMIT, ROLLBACK, SAVEPOINTConfirma ou desfaz alterações

SELECT e WHERE

O esqueleto de um SELECT é este.

SELECT [DISTINCT] coluna [AS alias], ...
FROM   tabela
WHERE  condição
ORDER BY coluna [ASC | DESC];
  • DISTINCT tira as linhas repetidas do resultado (só conta como repetida se a lista do SELECT inteira for igual)
  • O alias (apelido) vem depois de AS; se tiver espaços ou caracteres especiais, coloque-o entre aspas duplas
  • Para concatenar textos, o Oracle usa || e o SQL Server usa + (a função CONCAT existe nos dois)

Estes são os operadores que você usa no WHERE.

OperadorSignificadoAtenção
=, <>, !=, ^=, >, <, >=, <=Comparação<>, != e ^= significam todos “diferente de”
BETWEEN a AND bDe a até bInclui os dois extremos. O valor menor vem primeiro
IN (a, b, c)Igual a um dos itens da listaSe a lista do NOT IN tiver um NULL, nenhuma linha volta
LIKE 'A%'Padrão% é qualquer sequência de zero ou mais caracteres, _ é exatamente um caractere. Para procurar o próprio %, use ESCAPE
IS NULL / IS NOT NULLÉ NULL?= NULL é sempre “desconhecido”, então não volta nenhuma linha

Quando você liga várias condições, existe uma precedência. Pela documentação do Oracle, a ordem é parênteses → operadores de comparação → NOT → AND → OR. Como o AND vem antes do OR, A OR B AND C é calculado como A OR (B AND C). Na dúvida, use parênteses — é o jeito mais seguro.

Por que NOT IN (10, 20, NULL) não devolve nada? NOT IN vira “diferente de 10 AND diferente de 20 AND diferente de NULL”, e qualquer comparação com NULL dá sempre ‘desconhecido’, então a condição inteira nunca fica verdadeira. Se o resultado de uma subconsulta puder conter NULL, use NOT EXISTS ou filtre os NULLs antes.

ORDER BY: a ordenação e o lugar do NULL

O ORDER BY ordena em ordem crescente (ASC) por padrão, e você pode ordenar pelo nome da coluna, pelo alias ou pela posição na lista do SELECT (1, 2…). A diferença aparece no NULL. O Oracle trata o NULL como o maior valor e o coloca no fim em ordem crescente; o SQL Server o trata como o menor valor e o coloca no começo. No Oracle, você pode escolher o lugar dele com NULLS FIRST e NULLS LAST.

A ordem em que o SELECT é processado

Um comando SELECT não é processado na ordem em que é escrito. Conhecendo essa ordem, perguntas como “por que não consigo usar o alias no WHERE?” e “por que não posso usar SUM no WHERE?” se resolvem de uma vez. Avance as etapas na figura abaixo.

SELECT DEPT_CODE, SUM(SALARY) AS TOTAL
▶FROM EMP
WHERE SALARY >= 260
GROUP BY DEPT_CODE
HAVING SUM(SALARY) >= 280
ORDER BY TOTAL DESC;

EMP

EMP_NONAMEDEPT_CODESALARY
101AnaD10300
102BrunoD10250
103CaioD20400
104DéboraD20350
105EnzoNULL280
106FláviaD30260

Etapa 1 — FROM

Ordem de processamento
FROM

Avance as etapas. A ordem em que o comando é escrito (SELECT no topo) não é a ordem em que ele é processado.

O FROM vem primeiro. Ele traz as 6 linhas da tabela EMP. O SELECT está escrito no topo, mas na verdade é processado quase no fim.

Resumindo: FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY. O alias nasce no SELECT, então só dá para usá-lo no ORDER BY, que vem depois.

Se a questão disser… → escolha isto

  • “Número de colunas / número de linhas de uma relação”Grau / cardinalidade
  • “Atende à unicidade e à minimalidade”Chave candidata
  • “A chave estrangeira é um valor da tabela referenciada ou NULL”Integridade referencial
  • “Operação relacional que escolhe só as colunas desejadas”PROJECT (π)
  • “GRANT e REVOKE”DCL
  • “BETWEEN 100 AND 200”Inclui 100 e 200
  • “NULL na lista do NOT IN”0 linhas no resultado
  • “Lugar do NULL em ordem crescente no Oracle”No fim (no SQL Server, no começo)
  • “Por que o WHERE não aceita o alias do SELECT”O WHERE é processado antes do SELECT

02

Funções, GROUP BY e HAVING

Depois de tirar as colunas com o SELECT, é hora de transformar os valores (funções) e agrupar para contar (GROUP BY).

Funções de linha única: um valor por linha

Existem dois tipos de função: as funções de linha única, que devolvem um resultado para cada linha, e as funções de várias linhas (funções de agregação), que juntam várias linhas e devolvem um único resultado. As funções de linha única podem aparecer no SELECT, no WHERE e no ORDER BY, e dá até para colocar uma função dentro da outra.

TipoOracleSQL ServerExemplo e resultado
TextoLOWER, UPPERLOWER, UPPERUPPER('sql') → 'SQL'
SUBSTRSUBSTRINGSUBSTR('DATABASE', 3, 4) → 'TABA'
LENGTHLENLENGTH('SQL') → 3
LTRIM, RTRIM, TRIMLTRIM, RTRIM, TRIMTRIM(' A ') → 'A'
CONCAT, ||CONCAT, +'A' || 'B' → 'AB'
NúmeroROUND, TRUNCROUNDROUND(38.567, 1) → 38.6 / TRUNC(38.567, 1) → 38.5
CEIL, FLOORCEILING, FLOORCEIL(3.1) → 4 / FLOOR(-3.1) → -4
MOD%MOD(7, 3) → 1
DataSYSDATEGETDATE()Data e hora atuais
EXTRACTDATEPARTEXTRACT(YEAR FROM HIRE_DATE)

No Oracle, somar um número a uma data conta em dias: HIRE_DATE + 1 é o dia seguinte, e HIRE_DATE + 1/24 é uma hora depois. Outro detalhe: o Oracle trata a string vazia (‘’) como NULL, enquanto o SQL Server diferencia string vazia de NULL.

Conversão de tipos e CASE

Há duas formas de mudar o tipo de um dado: a conversão explícita, feita por você com uma função (Oracle: TO_CHAR, TO_NUMBER, TO_DATE; SQL Server: CAST, CONVERT), e a conversão implícita, que o banco de dados faz sozinho. A conversão implícita é prática, mas pode mudar o valor de um jeito inesperado ou impedir o uso de um índice, então é bom criar o hábito de converter explicitamente.

Para devolver valores diferentes conforme uma condição, use o CASE. Existe o CASE simples, que compara com um valor, e o CASE pesquisado, que usa expressões de condição. O Oracle também tem a função DECODE, que faz a mesma coisa.

SELECT NAME,
       CASE WHEN SALARY >= 350 THEN 'Alto'
            WHEN SALARY >= 280 THEN 'Médio'
            ELSE 'Baixo' END AS GRADE,      -- sem ELSE, o resultado é NULL
       DECODE(DEPT_CODE, 'D10', 'Vendas', 'D20', 'TI', 'Outros') AS DEPT_NAME
FROM   EMP;

Funções que lidam com NULL

FunçãoDevolveExemplo
NVL(a, b) / ISNULL(a, b)b se a for NULL; senão, aNVL(BONUS, 0)
NVL2(a, b, c)b se a não for NULL; c se for NULL (Oracle)NVL2(BONUS, 'Sim', 'Não')
NULLIF(a, b)NULL se a e b forem iguais; senão, aNULLIF(10, 10) → NULL
COALESCE(a, b, c, ...)O primeiro valor que não é NULLCOALESCE(NULL, NULL, 3) → 3

Funções de agregação e NULL

Funções de agregação como COUNT, SUM, AVG, MAX e MIN juntam várias linhas em um único valor. Só existe uma regra para guardar: todas ignoram o NULL, menos o COUNT(*). Troque a função na figura abaixo.

EMP

NAMESALARYBONUS
Ana30050
Bruno250NULL
Caio400NULL
Débora35030
Enzo280NULL
Flávia26020

COUNT(*) = 6

Cálculo
Linhas usadas
6 / 6

Troque a função. As linhas verdes entraram no cálculo; as riscadas ficaram de fora.

O COUNT(*) conta as próprias linhas. Uma linha com BONUS NULL continua sendo uma linha, então a resposta é 6.

Se você colocar DISTINCT dentro de uma função de agregação, os valores repetidos contam uma vez só (COUNT(DISTINCT DEPT_CODE)). Quando nenhuma linha atende à condição, o COUNT devolve 0, e SUM, AVG, MAX e MIN devolvem NULL.

GROUP BY e HAVING

O GROUP BY junta as linhas que têm o mesmo valor e agrega cada grupo. Depois de agrupar, cada grupo vira uma única linha, e isso traz algumas regras.

  • Toda coluna da lista do SELECT que estiver fora de uma função de agregação precisa estar também no GROUP BY
  • Não use o alias do SELECT no GROUP BY — pela ordem de processamento, o alias ainda não existe (o Oracle 23ai, a versão mais recente, permite, mas as provas seguem a regra tradicional)
  • O NULL também forma um grupo
  • O GROUP BY não garante ordenação — se precisar de ordem, use ORDER BY

Para colocar uma condição nos grupos, use o HAVING. O WHERE filtra as linhas antes de agrupar, e o HAVING filtra os grupos depois de agrupar. Por isso, condições com função de agregação só podem ir no HAVING. Se a condição não precisa de função de agregação, é melhor filtrar logo no WHERE, porque sobram menos linhas para processar.

SELECT   DEPT_CODE, COUNT(*) AS HEADCOUNT, AVG(SALARY) AS AVG_SAL
FROM     EMP
WHERE    SALARY >= 250          -- filtra as linhas primeiro
GROUP BY DEPT_CODE
HAVING   COUNT(*) >= 2;         -- filtra os grupos depois de agrupar

Se a questão disser… → escolha isto

  • “SUBSTR('DATABASE', 3, 4)”'TABA'
  • “String vazia no Oracle”Tratada como NULL
  • “NULL se a e b forem iguais”NULLIF(a, b)
  • “O primeiro valor que não é NULL”COALESCE
  • “Função de agregação que conta NULLs”Só o COUNT(*)
  • “AVG(BONUS) vs AVG(NVL(BONUS, 0))”Dividem por números de linhas diferentes
  • “Cláusula para condições com função de agregação”HAVING
  • “Coluna fora do GROUP BY no SELECT”Erro, a menos que esteja dentro de uma função de agregação

Exclusivo Pro

Até aqui vai a parte gratuita

Os outros 5 capítulos estão disponíveis para assinantes Pro. Cada um continua com visuais em 3D e dicas de “se a questão disser…”, e no último capítulo você testa o que aprendeu.

  1. 03Junções (JOIN)
  2. 04Subconsultas, views e operadores de conjunto
  3. 05Funções de grupo, funções de janela e Top N
  4. 06Autojunção, consultas hierárquicas, PIVOT e expressões regulares
  5. 07Comandos de gerenciamento: DML, TCL, DDL e DCL

Publicidade

PasslyExam

Você já leu o conceito. Agora teste com questões de prova

O PasslyExam oferece questões práticas originais, explicações e simulados completos baseados no guia oficial de cada certificação. As explicações mostram por que a opção certa está certa e por que as opções parecidas estão erradas. Cadastre-se e pratique de graça todos os dias.

Provas que cobrem este conceito

Mais guias sobre este tema

Guias de outros temas

Ver todos os guias