Funções Numéricas
Principais Funções para Números
ROUND - Arredondar
Arredonda um número para um número especificado de casas decimais.
SELECT ROUND(123.456, 2) FROM DUAL; -- 123.46
SELECT ROUND(123.456, 0) FROM DUAL; -- 123
SELECT ROUND(123.456, -1) FROM DUAL; -- 120 (arredonda dezenas)
SELECT ROUND(salario, -3) FROM funcionarios; -- Arredonda para milhares
TRUNC - Truncar
Remove casas decimais sem arredondar.
SELECT TRUNC(123.456, 2) FROM DUAL; -- 123.45 (sem arredondar)
SELECT TRUNC(123.456, 0) FROM DUAL; -- 123
SELECT TRUNC(123.456, -1) FROM DUAL; -- 120
MOD - Módulo (resto da divisão)
SELECT MOD(10, 3) FROM DUAL; -- 1 (resto de 10÷3)
SELECT MOD(15, 4) FROM DUAL; -- 3
-- Verificar números pares
SELECT nome, salario
FROM funcionarios
WHERE MOD(salario, 2) = 0; -- Salários pares
ABS - Valor Absoluto
SELECT ABS(-42) FROM DUAL; -- 42
SELECT ABS(42) FROM DUAL; -- 42
SELECT ABS(salario - 5000) FROM funcionarios; -- Diferença absoluta
CEIL e FLOOR - Arredondar para cima/baixo
SELECT CEIL(123.456) FROM DUAL; -- 124 (próximo inteiro acima)
SELECT FLOOR(123.456) FROM DUAL; -- 123 (próximo inteiro abaixo)
SELECT CEIL(-2.3) FROM DUAL; -- -2
SELECT FLOOR(-2.3) FROM DUAL; -- -3
Funções de String (Caracteres)
Conversão de Caso
UPPER, LOWER, INITCAP
SELECT UPPER('oracle database') FROM DUAL; -- ORACLE DATABASE
SELECT LOWER('ORACLE DATABASE') FROM DUAL; -- oracle database
SELECT INITCAP('oracle database') FROM DUAL; -- Oracle Database
-- Busca case-insensitive
SELECT nome FROM funcionarios
WHERE UPPER(nome) = UPPER('joão silva');
Manipulação de Strings
SUBSTR - Extrair Substring
SELECT SUBSTR('Oracle Database', 1, 6) FROM DUAL; -- Oracle (posição 1, 6 chars)
SELECT SUBSTR('Oracle Database', 8) FROM DUAL; -- Database (posição 8 até o fim)
SELECT SUBSTR('Oracle Database', -8) FROM DUAL; -- Database (8 chars do fim)
-- Extrair código de área de telefone
SELECT SUBSTR(telefone, 1, 4) AS ddd FROM clientes;
LENGTH - Tamanho da String
SELECT LENGTH('Oracle') FROM DUAL; -- 6
SELECT LENGTH('') FROM DUAL; -- NULL (string vazia = NULL)
-- Validar tamanho mínimo de senha
SELECT nome FROM usuarios
WHERE LENGTH(senha) < 8;
CONCAT e || (Concatenação)
SELECT CONCAT('Oracle', ' Database') FROM DUAL; -- Oracle Database
SELECT 'Oracle' || ' ' || 'Database' FROM DUAL; -- Oracle Database (operador ||)
-- Montar nome completo
SELECT nome || ' - ' || cargo AS identificacao
FROM funcionarios;
-- Concatenar múltiplas colunas
SELECT CONCAT(CONCAT(nome, ' ('), CONCAT(cargo, ')')) FROM funcionarios;
TRIM, LTRIM, RTRIM - Remover Espaços
SELECT TRIM(' Oracle ') FROM DUAL; -- Oracle
SELECT LTRIM(' Oracle ') FROM DUAL; -- 'Oracle '
SELECT RTRIM(' Oracle ') FROM DUAL; -- ' Oracle'
-- Remover caracteres específicos
SELECT TRIM('x' FROM 'xxxOraclexxx') FROM DUAL; -- Oracle
-- Limpar dados de entrada
UPDATE clientes
SET email = TRIM(email)
WHERE email != TRIM(email);
LPAD e RPAD - Preencher com Caracteres
SELECT LPAD('42', 5, '0') FROM DUAL; -- 00042
SELECT RPAD('Oracle', 10, '.') FROM DUAL; -- Oracle....
-- Formatar IDs com zeros à esquerda
SELECT LPAD(id_funcionario, 6, '0') AS codigo_formatado
FROM funcionarios;
-- Criar máscaras
SELECT LPAD(SUBSTR(cpf, -4, 4), LENGTH(cpf), '*') AS cpf_mascarado
FROM clientes;
Funções de Data e Hora
Obter Data Atual
SYSDATE e CURRENT_DATE
SELECT SYSDATE FROM DUAL; -- Data/hora do servidor
SELECT CURRENT_DATE FROM DUAL; -- Data/hora da sessão
-- Usar em INSERT
INSERT INTO logs (id, mensagem, data_hora)
VALUES (1, 'Sistema iniciado', SYSDATE);
Aritmética com Datas
ADD_MONTHS - Adicionar Meses
SELECT ADD_MONTHS(SYSDATE, 3) FROM DUAL; -- Daqui a 3 meses
SELECT ADD_MONTHS(SYSDATE, -6) FROM DUAL; -- Há 6 meses atrás
-- Calcular vencimento de contrato
SELECT nome, data_contratacao,
ADD_MONTHS(data_contratacao, 12) AS fim_contrato
FROM funcionarios;
MONTHS_BETWEEN - Diferença em Meses
SELECT MONTHS_BETWEEN(SYSDATE, DATE '2020-01-01') FROM DUAL;
-- Calcular tempo de empresa
SELECT nome,
ROUND(MONTHS_BETWEEN(SYSDATE, data_admissao) / 12, 1) AS anos_empresa
FROM funcionarios;
Operações Aritméticas Diretas
SELECT SYSDATE + 7 FROM DUAL; -- Daqui a 7 dias
SELECT SYSDATE - 30 FROM DUAL; -- Há 30 dias
-- Diferença entre datas em dias
SELECT nome, SYSDATE - data_admissao AS dias_empresa
FROM funcionarios;
-- Adicionar horas (1/24 = 1 hora)
SELECT SYSDATE + (2/24) FROM DUAL; -- Daqui a 2 horas
TRUNC com Datas - Truncar Parte do Tempo
SELECT TRUNC(SYSDATE) FROM DUAL; -- Remove hora (00:00:00)
SELECT TRUNC(SYSDATE, 'MM') FROM DUAL; -- Primeiro dia do mês
SELECT TRUNC(SYSDATE, 'YYYY') FROM DUAL; -- Primeiro dia do ano
SELECT TRUNC(SYSDATE, 'Q') FROM DUAL; -- Primeiro dia do trimestre
-- Comparar apenas datas (sem hora)
SELECT * FROM pedidos
WHERE TRUNC(data_pedido) = TRUNC(SYSDATE);
EXTRACT - Extrair Parte da Data
SELECT EXTRACT(YEAR FROM SYSDATE) FROM DUAL; -- 2024
SELECT EXTRACT(MONTH FROM SYSDATE) FROM DUAL; -- 12
SELECT EXTRACT(DAY FROM SYSDATE) FROM DUAL; -- 17
-- Agrupar vendas por ano
SELECT EXTRACT(YEAR FROM data_venda) AS ano,
COUNT(*) AS total_vendas
FROM vendas
GROUP BY EXTRACT(YEAR FROM data_venda);
Funções de Conversão
Conversões de Tipo
TO_CHAR - Converter para String
-- Números para string
SELECT TO_CHAR(12345.67) FROM DUAL; -- '12345.67'
SELECT TO_CHAR(12345.67, '999,999.99') FROM DUAL; -- ' 12,345.67'
SELECT TO_CHAR(12345.67, 'L999,999.99') FROM DUAL; -- 'R$ 12,345.67' (local)
SELECT TO_CHAR(salario, 'FM999G999G990D00') FROM funcionarios; -- Formato brasileiro
-- Datas para string
SELECT TO_CHAR(SYSDATE, 'DD/MM/YYYY') FROM DUAL; -- 17/12/2025
SELECT TO_CHAR(SYSDATE, 'DD/MM/YYYY HH24:MI:SS') FROM DUAL;
SELECT TO_CHAR(SYSDATE, 'Day, DD "de" Month "de" YYYY') FROM DUAL;
SELECT TO_CHAR(SYSDATE, 'DY') FROM DUAL; -- Seg, Ter, etc.
-- Formatos úteis
SELECT TO_CHAR(data_pedido, 'YYYY-MM') AS mes_ano
FROM pedidos
GROUP BY TO_CHAR(data_pedido, 'YYYY-MM');
TO_NUMBER - Converter String para Número
SELECT TO_NUMBER('12345') FROM DUAL; -- 12345
SELECT TO_NUMBER('12,345.67', '99,999.99') FROM DUAL; -- 12345.67
-- Converter e calcular
SELECT TO_NUMBER('100') + TO_NUMBER('200') FROM DUAL; -- 300
-- Útil ao importar dados CSV
UPDATE tabela_temp
SET valor_numerico = TO_NUMBER(valor_string, '999999.99');
TO_DATE - Converter String para Data
SELECT TO_DATE('17/12/2025', 'DD/MM/YYYY') FROM DUAL;
SELECT TO_DATE('2025-12-17', 'YYYY-MM-DD') FROM DUAL;
SELECT TO_DATE('17-DEC-25', 'DD-MON-YY') FROM DUAL;
SELECT TO_DATE('17/12/2025 14:30:00', 'DD/MM/YYYY HH24:MI:SS') FROM DUAL;
-- Usar em condições WHERE
SELECT * FROM pedidos
WHERE data_pedido >= TO_DATE('01/01/2025', 'DD/MM/YYYY')
AND data_pedido < TO_DATE('01/02/2025', 'DD/MM/YYYY');
Formatos Comuns
- DD/MM/YYYY - 17/12/2025
- YYYY-MM-DD - 2025-12-17
- DD-MON-YY - 17-DEC-25
- HH24:MI:SS - 14:30:00
- 999,999.99 - separadores
- FM - remove espaços
- L - símbolo da moeda local
- G - separador de milhar
Funções Condicionais e NULL
Tratamento de NULL
NVL - Substituir NULL
SELECT NVL(comissao, 0) FROM funcionarios; -- Se NULL, usa 0
SELECT NVL(telefone, 'Não informado') FROM clientes; -- Se NULL, usa texto
-- Calcular com NULL tratado
SELECT nome, salario, NVL(comissao, 0) AS comissao,
salario + NVL(comissao, 0) AS total
FROM funcionarios;
NVL2 - Valor se NULL ou NÃO NULL
-- NVL2(expressão, valor_se_não_null, valor_se_null)
SELECT NVL2(comissao, 'Sim', 'Não') AS tem_comissao
FROM funcionarios;
SELECT nome,
NVL2(data_demissao, 'Inativo', 'Ativo') AS status
FROM funcionarios;
COALESCE - Primeiro valor não NULL
-- Retorna o primeiro valor não NULL da lista
SELECT COALESCE(telefone_celular, telefone_residencial,
telefone_comercial, 'Sem telefone') AS contato
FROM clientes;
SELECT COALESCE(email_principal, email_secundario, 'nao@informado.com')
FROM usuarios;
Lógica Condicional
DECODE - Condicional Simples
-- DECODE(coluna, valor1, resultado1, valor2, resultado2, ..., padrão)
SELECT nome,
DECODE(departamento_id,
10, 'Tecnologia',
20, 'RH',
30, 'Financeiro',
'Outros') AS departamento
FROM funcionarios;
SELECT nome,
DECODE(SIGN(salario - 5000),
1, 'Alto', -- salario > 5000
0, 'Médio', -- salario = 5000
-1, 'Baixo') AS faixa_salarial
FROM funcionarios;
CASE - Condicional Avançada (SQL Padrão)
-- CASE simples (igual ao DECODE)
SELECT nome,
CASE departamento_id
WHEN 10 THEN 'Tecnologia'
WHEN 20 THEN 'RH'
WHEN 30 THEN 'Financeiro'
ELSE 'Outros'
END AS departamento
FROM funcionarios;
-- CASE com condições complexas (mais poderoso)
SELECT nome, salario,
CASE
WHEN salario < 3000 THEN 'Júnior'
WHEN salario BETWEEN 3000 AND 7000 THEN 'Pleno'
WHEN salario > 7000 THEN 'Sênior'
ELSE 'Não classificado'
END AS nivel
FROM funcionarios;
-- CASE aninhado
SELECT nome,
CASE
WHEN departamento_id = 10 THEN
CASE
WHEN salario > 8000 THEN 'TI - Sênior'
ELSE 'TI - Júnior'
END
WHEN departamento_id = 20 THEN 'RH'
ELSE 'Outros'
END AS classificacao
FROM funcionarios;
Exemplos Práticos Combinados
Exemplo 1: Relatório de Funcionários Formatado
SELECT
LPAD(id_funcionario, 6, '0') AS codigo,
INITCAP(nome) AS funcionario,
UPPER(cargo) AS cargo,
TO_CHAR(salario, 'L999G999D00') AS salario_formatado,
TO_CHAR(data_admissao, 'DD/MM/YYYY') AS admissao,
ROUND(MONTHS_BETWEEN(SYSDATE, data_admissao) / 12, 1) AS anos_empresa,
CASE
WHEN MONTHS_BETWEEN(SYSDATE, data_admissao) / 12 < 1 THEN 'Novo'
WHEN MONTHS_BETWEEN(SYSDATE, data_admissao) / 12 < 5 THEN 'Experiente'
ELSE 'Veterano'
END AS categoria,
NVL(TO_CHAR(comissao, '999.99'), 'N/A') AS comissao
FROM funcionarios
ORDER BY anos_empresa DESC;
Exemplo 2: Análise de Vendas
SELECT
EXTRACT(YEAR FROM data_venda) AS ano,
EXTRACT(MONTH FROM data_venda) AS mes,
TO_CHAR(data_venda, 'Month') AS nome_mes,
COUNT(*) AS total_vendas,
TO_CHAR(SUM(valor), 'L999G999G990D00') AS total_formatado,
ROUND(AVG(valor), 2) AS ticket_medio,
CASE
WHEN SUM(valor) > 100000 THEN 'Excelente'
WHEN SUM(valor) > 50000 THEN 'Bom'
ELSE 'Regular'
END AS performance
FROM vendas
WHERE data_venda >= ADD_MONTHS(TRUNC(SYSDATE, 'YYYY'), -12)
GROUP BY
EXTRACT(YEAR FROM data_venda),
EXTRACT(MONTH FROM data_venda),
TO_CHAR(data_venda, 'Month')
ORDER BY ano DESC, mes DESC;
Exemplo 3: Validação e Limpeza de Dados
SELECT
id_cliente,
TRIM(nome) AS nome_limpo,
UPPER(TRIM(email)) AS email_padronizado,
CASE
WHEN LENGTH(TRIM(telefone)) = 11 THEN
'(' || SUBSTR(telefone, 1, 2) || ') ' ||
SUBSTR(telefone, 3, 5) || '-' || SUBSTR(telefone, 8, 4)
ELSE 'Telefone Inválido'
END AS telefone_formatado,
CASE
WHEN email LIKE '%@%' THEN 'Válido'
ELSE 'Inválido'
END AS status_email,
COALESCE(NULLIF(TRIM(endereco), ''), 'Não informado') AS endereco,
ROUND((SYSDATE - data_cadastro), 0) AS dias_cadastrado,
DECODE(SIGN(SYSDATE - ultima_compra - 90),
1, 'Inativo',
-1, 'Ativo',
'Cliente Novo') AS status_cliente
FROM clientes;
Resultado Esperado
O que você deve dominar após este tópico:
Funções numéricas
ROUND, TRUNC, MOD, ABS, CEIL, FLOOR
Manipular strings
UPPER, LOWER, SUBSTR, LENGTH, CONCAT, TRIM, LPAD/RPAD
Trabalhar com datas
SYSDATE, ADD_MONTHS, MONTHS_BETWEEN, TRUNC, EXTRACT
Converter tipos
TO_CHAR, TO_NUMBER, TO_DATE com formatos
Tratar NULLs
NVL, NVL2, COALESCE
Lógica condicional
DECODE, CASE para decisões em SQL
Exercícios Práticos
Exercício 1: Formatação de Relatório
Crie uma query que mostre funcionários com: nome em maiúsculas, salário formatado em reais, tempo de empresa em anos (arredondado) e categoria (Júnior/Pleno/Sênior baseado no salário).
Ver Solução
SELECT
UPPER(nome) AS nome,
TO_CHAR(salario, 'L999G999D00') AS salario,
ROUND(MONTHS_BETWEEN(SYSDATE, data_admissao) / 12, 1) AS anos,
CASE
WHEN salario < 4000 THEN 'Júnior'
WHEN salario BETWEEN 4000 AND 8000 THEN 'Pleno'
ELSE 'Sênior'
END AS categoria
FROM funcionarios
ORDER BY salario DESC;
Exercício 2: Manipulação de Strings
Extraia os 3 primeiros caracteres do nome, converta para maiúsculas e concatene com o ID formatado com zeros à esquerda (6 dígitos) para criar um código único.
Ver Solução
SELECT
id_funcionario,
nome,
UPPER(SUBSTR(nome, 1, 3)) || LPAD(id_funcionario, 6, '0') AS codigo_unico
FROM funcionarios;
Exercício 3: Análise Temporal
Liste funcionários admitidos nos últimos 90 dias, mostrando nome, data de admissão formatada, dias desde admissão e o dia da semana da admissão.
Ver Solução
SELECT
nome,
TO_CHAR(data_admissao, 'DD/MM/YYYY') AS data_admissao,
ROUND(SYSDATE - data_admissao, 0) AS dias_admitido,
TO_CHAR(data_admissao, 'Day') AS dia_semana
FROM funcionarios
WHERE data_admissao >= SYSDATE - 90
ORDER BY data_admissao DESC;