COALESCE e NULLIF: lidando com nulos
1. Introdução aos valores NULL no SQL
NULL em SQL não é zero, nem string vazia, nem qualquer outro valor. NULL representa a ausência de valor — um dado desconhecido, não informado ou inexistente. Essa distinção é crucial: enquanto zero é um valor numérico e '' é uma string vazia, NULL indica que simplesmente não há dado.
Os problemas causados por NULL são notórios:
- Em cálculos aritméticos, qualquer operação envolvendo NULL resulta em NULL
- Em agregações como AVG() ou SUM(), NULLs são ignorados, mas podem distorcer resultados
- Em junções (JOIN), colunas com NULL não correspondem a nada, nem mesmo a outro NULL
- Em cláusulas WHERE, coluna = NULL nunca é verdadeiro — deve-se usar IS NULL
Para lidar com esses desafios, o SQL oferece funções especializadas: COALESCE, NULLIF, NVL (Oracle) e ISNULL (SQL Server). Este artigo foca nas duas primeiras, que são padrão ANSI e funcionam na maioria dos bancos.
2. COALESCE: Sintaxe e Funcionamento Básico
A sintaxe do COALESCE é:
COALESCE(valor1, valor2, ..., valorN)
A função avalia os argumentos na ordem em que são fornecidos e retorna o primeiro valor não nulo. Se todos os argumentos forem NULL, o resultado é NULL.
Exemplo simples:
SELECT COALESCE(NULL, NULL, 'terceiro', 'quarto') AS resultado;
-- Resultado: 'terceiro'
Em uma tabela de clientes:
SELECT
nome,
COALESCE(telefone, 'Não informado') AS telefone_contato
FROM clientes;
Aqui, clientes sem telefone cadastrado exibem "Não informado" em vez de NULL.
3. Casos de Uso Práticos com COALESCE
Preenchimento em relatórios:
SELECT
produto,
COALESCE(descricao, 'Sem descrição') AS descricao,
COALESCE(preco, 0.00) AS preco
FROM produtos;
Combinação de colunas alternativas:
SELECT
nome,
COALESCE(telefone_celular, telefone_fixo, email, 'Sem contato') AS contato_principal
FROM funcionarios;
Isso cria uma hierarquia: usa celular se existir; senão, tenta fixo; depois email; por fim, um fallback.
Expressões aritméticas seguras:
SELECT
id_pedido,
COALESCE(quantidade, 0) * COALESCE(preco_unitario, 0) AS valor_total
FROM itens_pedido;
Sem COALESCE, se qualquer coluna for NULL, o resultado de quantidade * preco_unitario seria NULL.
4. NULLIF: Sintaxe e Funcionamento Básico
A sintaxe do NULLIF é:
NULLIF(expressão1, expressão2)
A lógica é direta: se expressão1 for igual a expressão2, retorna NULL; caso contrário, retorna expressão1.
Exemplo simples:
SELECT NULLIF(10, 10) AS resultado1; -- NULL
SELECT NULLIF(10, 20) AS resultado2; -- 10
Prevenção de divisão por zero:
SELECT
produto,
receita / NULLIF(quantidade, 0) AS preco_medio
FROM vendas;
Se quantidade for zero, NULLIF retorna NULL, e a divisão receita / NULL resulta em NULL — evitando o erro de divisão por zero.
5. Casos de Uso Práticos com NULLIF
Cálculos financeiros seguros:
SELECT
mes,
SUM(receita) / NULLIF(COUNT(vendas), 0) AS receita_media_por_venda
FROM relatorio_mensal
GROUP BY mes;
Marcação de valores redundantes:
SELECT
nome,
NULLIF(email_principal, email_secundario) AS email_diferente
FROM usuarios;
Se os dois emails forem idênticos, retorna NULL — indicando redundância.
Limpeza de dados sentinela:
UPDATE clientes
SET idade = NULLIF(idade, -1)
WHERE idade = -1;
Valores como -1 ou 9999 são frequentemente usados como "não informado" em sistemas legados. NULLIF os converte para NULL padronizado.
6. COALESCE e NULLIF Trabalhando Juntos
A combinação dessas funções permite lógica condicional robusta em uma única expressão.
Substituir zero por um padrão:
SELECT
produto,
COALESCE(NULLIF(estoque, 0), 1) AS estoque_ajustado
FROM produtos;
Aqui, NULLIF(estoque, 0) transforma zero em NULL, e COALESCE substitui esse NULL por 1. O resultado: todos os estoques zero são tratados como 1.
Evitar valores indesejados em relatórios:
SELECT
funcionario,
COALESCE(NULLIF(comissao, 0), NULLIF(bonus, 0), 0) AS remuneracao_variavel
FROM pagamentos;
Isso prioriza comissão, depois bônus, mas ignora valores zero (tratando-os como ausentes).
Padrão para substituir string vazia:
SELECT
cliente,
COALESCE(NULLIF(observacao, ''), 'Sem observação') AS obs_formatada
FROM cadastro;
7. Comparação com Alternativas (NVL, ISNULL, CASE)
NVL (Oracle) vs COALESCE:
-- Oracle
NVL(coluna, 'padrão') -- apenas 2 argumentos
COALESCE(coluna1, coluna2, coluna3, 'padrão') -- N argumentos
NVL é limitado a dois argumentos. COALESCE é mais flexível e padrão ANSI.
ISNULL (SQL Server) vs COALESCE:
-- SQL Server
ISNULL(coluna, 0) -- tipos devem ser compatíveis
COALESCE(coluna, 0) -- pode ter problemas de tipo com strings vs números
No SQL Server, ISNULL preserva o tipo do primeiro argumento, enquanto COALESCE tenta determinar o tipo de maior precedência entre todos os argumentos.
CASE WHEN para lógica complexa:
SELECT
CASE
WHEN coluna1 IS NOT NULL THEN coluna1
WHEN coluna2 > 0 THEN coluna2
ELSE 'padrão'
END AS resultado;
Use CASE quando a lógica envolver condições que não são simplesmente "primeiro não nulo" ou "igualdade".
8. Boas Práticas e Armadilhas Comuns
Tipos de dados incompatíveis:
-- Problema: misturar string e número
SELECT COALESCE(idade, 'não informado') FROM pessoas;
-- Erro em muitos bancos: tipos incompatíveis
Solução: converter explicitamente ou usar valores padrão do mesmo tipo.
Performance em grandes volumes:
COALESCEé geralmente eficiente, mas avaliar muitos argumentos tem custoISNULL(SQL Server) pode ser ligeiramente mais rápido queCOALESCEem cenários simplesCASEcom múltiplas condições pode ser mais lento queCOALESCEpara a mesma lógica
Filtragem correta em WHERE:
-- Errado: não funciona com NULL
SELECT * FROM clientes WHERE email = NULL;
-- Correto
SELECT * FROM clientes WHERE email IS NULL;
SELECT * FROM clientes WHERE COALESCE(email, '') = '';
Uso em JOINs:
-- Cuidado: NULL nunca é igual a NULL
SELECT * FROM a JOIN b ON a.coluna = b.coluna;
-- Se ambas forem NULL, a linha não será incluída
-- Solução: tratar NULLs explicitamente
SELECT * FROM a JOIN b ON COALESCE(a.coluna, '') = COALESCE(b.coluna, '');
Dominar COALESCE e NULLIF é essencial para escrever SQL robusto e previsível. Essas funções transformam o tratamento de nulos de uma dor de cabeça em uma ferramenta elegante de expressividade e segurança.
Referências
- Documentação oficial PostgreSQL: COALESCE e NULLIF — Explicação detalhada das funções condicionais, incluindo exemplos e comportamento com tipos de dados.
- Microsoft SQL Server: ISNULL vs COALESCE — Documentação oficial com comparação entre ISNULL e COALESCE, diferenças de tipo e desempenho.
- Oracle Database: NVL e COALESCE — Referência oficial Oracle com exemplos de NVL, NULLIF e COALESCE.
- SQLite: NULLIF e COALESCE na prática — Documentação do SQLite com exemplos claros de uso em consultas.
- MySQL: Funções de fluxo de controle — Documentação MySQL cobrindo COALESCE, NULLIF, IFNULL e CASE com exemplos práticos.
- SQL Shack: Tratamento de NULLs com COALESCE e NULLIF — Tutorial prático com exemplos do mundo real, incluindo prevenção de divisão por zero e preenchimento de relatórios.
- Mode Analytics: Guia de funções SQL para NULL — Tutorial interativo com exemplos de COALESCE, NULLIF e outras funções para tratamento de nulos.