Introdução
As funções avançadas em SQL vão além de operações básicas, como selecionar e filtrar dados. Elas permitem realizar cálculos complexos, manipular strings, trabalhar com datas e analisar dados de maneiras mais sofisticadas. Essas funções ajudam a obter insights, transformar dados e criar relatórios mais significativos a partir do seu banco de dados.
Essas funções são dividas em algumas categorias:
- Funções Numéricas
- Funções de String
- Funções Condicionais
- Funções de Data
Funções Numéricas
FLOOR(x) — arredonda para baixo
Sempre “empurra” o número para o inteiro menor ou igual, independente do sinal.
FLOOR(4.7)-- 4
FLOOR(4.1)-- 4
FLOOR(-4.1)-- -5 (atenção: vai para o lado mais negativo, não trunca!)
Enter fullscreen mode Exit fullscreen mode
Uso real: calcular quantas “páginas cheias” cabem em uma lista, ou converter minutos em horas completas: FLOOR(minutos / 60).
CEILING(x) — arredonda para cima
O oposto do FLOOR: sempre vai para o inteiro maior ou igual.
CEILING(4.1)-- 5
CEILING(-4.7)-- -4
Enter fullscreen mode Exit fullscreen mode
Uso real: calcular quantos caminhões/caixas você precisa. Se cada caixa cabe 10 itens e você tem 23 itens, precisa de CEILING(23/10.0) = 3 caixas (não 2, que sobraria item de fora).
ROUND(x, n) — arredondamento matemático padrão
n é o número de casas decimais, pode ser negativo para arredondar dezenas/centenas.
ROUND(4.567,2)-- 4.57
ROUND(4.565,2)-- 4.56 ou 4.57 (depende do motor — arredondamento bancário vs. "meio para cima")
ROUND(1234,-2)-- 1200 (arredonda para centena mais próxima)
Enter fullscreen mode Exit fullscreen mode
⚠️ Cuidado: o comportamento no .5 exato (round half up vs. round half even/”banker’s rounding”) varia entre bancos — SQL Server e PostgreSQL não tratam igual. Nunca confie em ROUND para regras fiscais sem testar no seu banco específico.
ABS(x) — valor absoluto
Remove o sinal.
ABS(-15)-- 15
ABS(15)-- 15
Enter fullscreen mode Exit fullscreen mode
Uso real: calcular diferença entre duas datas/valores sem se importar com qual é maior: ABS(preco_atual - preco_anterior) para medir variação, independente de subida ou queda.
MOD(a, b) — resto da divisão
Equivalente ao operador % em outras linguagens. Note que MOD é uma função em Oracle/MySQL; SQL Server usa o operador % diretamente.
MOD(10,3)-- 1
MOD(9,3)-- 0
MOD(-7,3)-- -1 (sinal segue o dividendo `a`, na maioria dos bancos)
Enter fullscreen mode Exit fullscreen mode
Usos reais:
- Paridade:
MOD(id, 2) = 0→ linhas pares (útil para zebra striping em relatórios). - Distribuir dados em N grupos/partições:
MOD(id, 4)gera 4 grupos (0,1,2,3). - Ciclos: dia da semana, rodízio de placas, etc.
Funções de String
LENGTH(s) — tamanho da string
Conta caracteres (não bytes, na maioria dos bancos com suporte a Unicode).
LENGTH('abc')-- 3
LENGTH('')-- 0
LENGTH(NULL)-- NULL (não é 0!)
LENGTH('café')-- 4 caracteres (mas pode variar em bytes se for UTF-8 e você usar OCTET_LENGTH)
Enter fullscreen mode Exit fullscreen mode
⚠️ SQL Server usa LEN() em vez de LENGTH(). Cuidado com espaços em branco à direita — LEN() no SQL Server os ignora, mas LENGTH() no Postgres/MySQL não.
CONCAT(a, b, ...)
Antes do CONCAT existir como função padrão, cada banco usava um operador diferente para juntar strings:
+
MySQL
CONCAT() (não suporta `
O {% raw %}CONCAT() como função é a forma padrão ANSI, suportada por praticamente todos os bancos modernos — por isso é a escolha mais portável.
A diferença crucial: tratamento de NULL
Essa é a parte mais importante e mais fonte de bugs:
-- Com operador (Postgres, Oracle, SQL Server antigo)
SELECT 'Rua ' || nome_rua|| ', ' || numero;
-- Se numero for NULL → resultado inteiro é NULL!
-- Com CONCAT (padrão ANSI, MySQL, Postgres 9+, SQL Server 2012+)
SELECT CONCAT('Rua ', nome_rua,', ', numero);
-- Se numero for NULL → NULL é tratado como '' (string vazia)
-- Resultado: 'Rua das Flores, ' (não quebra a linha inteira)
Enter fullscreen mode Exit fullscreen mode
Por que isso importa na prática: imagine montar um endereço completo com 5 campos concatenados. Se você usar || e um único campo (tipo complemento, que é opcional) for NULL, o endereço inteiro vira NULL — some da tela. Com CONCAT(), só aquele pedaço fica vazio, o resto aparece normalmente.
-- Exemplo real: monte um endereço, onde "complemento" costuma ser NULL
SELECT CONCAT(logradouro, ', ', numero, ' - ', COALESCE(complemento, ''), ' ', bairro) AS endereco_completo
FROM clientes;
Enter fullscreen mode Exit fullscreen mode
SUBSTRING(s, início, tamanho) — extrai parte da string
Índice começa em 1 (não em 0!).
SUBSTRING('12345678900',1,3)-- '123'
SUBSTRING('12345678900',4,3)-- '456'
SUBSTRING('abcdef',3)-- 'cdef' (sem tamanho, pega até o fim — funciona no Postgres, não em todos)
Enter fullscreen mode Exit fullscreen mode
Usos reais:
- Extrair parte de um documento: DDD do telefone, os 3 primeiros dígitos do CPF.
- Mascarar dados sensíveis: mostrar só os últimos 4 dígitos de um cartão.
CONCAT('****',SUBSTRING(cartao,LENGTH(cartao)- 3,4))
Enter fullscreen mode Exit fullscreen mode
REPLACE(s, de, para) — substitui todas as ocorrências
Substitui todas as ocorrências de de por para (não é case-sensitive de forma consistente — depende do collation do banco).
REPLACE('2026-07-21','-','/')-- '2026/07/21'
REPLACE('aaa','a','bb')-- 'bbbbbb'
Enter fullscreen mode Exit fullscreen mode
Uso real: limpar formatação antes de salvar (remover pontos/traços de CPF/CNPJ), normalizar separadores decimais (, → .) vindos de importação de planilha.
UPPER(s) / LOWER(s) — maiúsculas/minúsculas
UPPER('sql')-- 'SQL'
LOWER('SQL')-- 'sql'
Enter fullscreen mode Exit fullscreen mode
Uso real mais importante: comparações case-insensitive sem depender do collation da coluna:
WHERE LOWER(email)= LOWER('[email protected]')
Enter fullscreen mode Exit fullscreen mode
Isso é comum quando o banco tem collation case-sensitive e você quer garantir que “[email protected]” e “[email protected]” sejam tratados como iguais.
Funções Condicionais
CASE — estrutura condicional
Duas sintaxes:
CASE simples (compara uma expressão contra valores):
CASE status
WHEN 'A' THEN 'Ativo'
WHEN 'I' THEN 'Inativo'
ELSE 'Desconhecido'
END
Enter fullscreen mode Exit fullscreen mode
CASE com busca (searched CASE) — mais flexível, permite condições complexas:
CASE
WHEN idade < 18 THEN 'Menor'
WHEN idade BETWEEN 18 AND 65 THEN 'Adulto'
WHEN idade > 65 THEN 'Idoso'
ELSE 'Não informado'
END
Enter fullscreen mode Exit fullscreen mode
Regras importantes:
- Avalia condições em ordem e para na primeira verdadeira — a ordem importa.
- Se
ELSEfor omitido e nada bater, retornaNULL. - Pode ser usado em
SELECT,WHERE,ORDER BYe até dentro deSUM()/COUNT()para agregações condicionais:
NULLIF(a, b) — retorna NULL se forem iguais
NULLIF(5, 5) -- NULL
NULLIF(5, 3) -- 5 (retorna 'a' quando são diferentes)
Enter fullscreen mode Exit fullscreen mode
É literalmente um atalho para CASE WHEN a = b THEN NULL ELSE a END
Ou seja: compara a com b. Se forem iguais, retorna NULL. Se forem diferentes, retorna a (nunca b — isso é importante, a função não é simétrica no retorno, mesmo que a comparação seja).
NULLIF(10,10)-- NULL
NULLIF(10,5)-- 10 (retorna 'a', não importa o valor de 'b')
NULLIF(5,10)-- 5
Enter fullscreen mode Exit fullscreen mode
COALESCE(a, b, c, ...) — primeiro valor não-nulo
Percorre a lista da esquerda para a direita e retorna o primeiro argumento que não é NULL.
COALESCE(NULL,NULL,'terceiro','quarto')-- 'terceiro'
COALESCE(telefone_celular, telefone_fixo, email,'sem contato')
Enter fullscreen mode Exit fullscreen mode
Funções de Data e Hora
DATE, TIME, TIMESTAMP — tipos e extração
Não são bem “funções” isoladas — são tipos de dado (DATE = só data, TIME = só hora, TIMESTAMP/DATETIME = ambos), mas também aparecem como funções de conversão/cast:
CAST(coluna_timestampAS DATE)-- extrai só a data, descarta a hora
CAST(coluna_timestampAS TIME)-- extrai só a hora
CURRENT_TIMESTAMP-- data+hora atual (padrão ANSI)
CURRENT_DATE-- só a data atual
Enter fullscreen mode Exit fullscreen mode
Uso real: você tem uma coluna created_at TIMESTAMP e quer agrupar por dia, ignorando a hora:
SELECT CAST(created_at AS DATE) AS dia,COUNT(*)
FROM pedidos
GROUP BY CAST(created_at AS DATE);
Enter fullscreen mode Exit fullscreen mode
Sem esse cast, cada created_at com hora diferente formaria um grupo distinto.
DATEPART(parte, data) — extrai um componente
Sintaxe do SQL Server. Extrai um pedaço específico da data como número.
DATEPART(YEAR,'2026-07-21')-- 2026
DATEPART(MONTH,'2026-07-21')-- 7
DATEPART(DAY,'2026-07-21')-- 21
DATEPART(WEEKDAY,'2026-07-21')-- dia da semana (numérico)
DATEPART(QUARTER,'2026-07-21')-- 3 (terceiro trimestre)
Enter fullscreen mode Exit fullscreen mode
Equivalentes em outros bancos:
-
PostgreSQL:
EXTRACT(YEAR FROM data) -
MySQL:
YEAR(data),MONTH(data),DAY(data)
Uso real: relatórios agrupados por período — vendas por mês, por trimestre, por ano:
SELECT DATEPART(YEAR, data_pedido) AS ano,DATEPART(MONTH, data_pedido) AS mes,SUM(valor)
FROM pedidos
GROUP BY DATEPART(YEAR, data_pedido), DATEPART(MONTH, data_pedido);
Enter fullscreen mode Exit fullscreen mode
DATEADD(parte, n, data) — soma/subtrai intervalo
DATEADD(DAY,30,'2026-07-21')-- 2026-08-20
DATEADD(MONTH,-1,'2026-07-21')-- 2026-06-21
DATEADD(YEAR,1,'2026-07-21')-- 2027-07-21
Enter fullscreen mode Exit fullscreen mode
n negativo subtrai. Equivalentes:
-
PostgreSQL:
data + INTERVAL '30 days' -
MySQL:
DATE_ADD(data, INTERVAL 30 DAY)
Usos reais:
- Data de vencimento:
DATEADD(DAY, 30, data_pedido). - Janela de tempo relativa a hoje:
WHERE data_pedido >= DATEADD(DAY, -7, GETDATE())→ últimos 7 dias. - Calcular idade:
DATEDIFF(YEAR, data_nascimento, GETDATE())(função irmã doDATEADD).
답글 남기기