A maioria dos principais RDBMSs suportam o
NULLIF()
operador, que retorna NULL
se ambos os argumentos forem equivalentes. Se os argumentos não forem equivalentes, NULLIF()
retorna o primeiro argumento. NULLIF()
é um recurso padrão SQL (está incluído na especificação ISO/IEC 9075). Sintaxe
A sintaxe fica assim:
NULLIF (V1, V2)
Isso é equivalente ao seguinte
CASE
expressão:CASE WHEN V1=V2 THEN NULL ELSE V1 END
Exemplo
Segue um exemplo para demonstrar:
SELECT NULLIF( 12, 12 );
Resultado:
NULL
Nesse caso, ambos os argumentos são idênticos e, portanto, o resultado é
NULL
. Dependendo do seu RDBMS, a saída real para valores NULL pode ser diferente. Por exemplo, ao usar o psql (para PostgreSQL), a string vazia é gerada por padrão sempre que um valor NULL é retornado (embora isso possa ser alterado). É o mesmo com o SQLite (e isso também pode ser alterado).
Quando os argumentos não são equivalentes
Aqui está o que acontece quando os argumentos não são equivalentes:
SELECT NULLIF( 12, 13 );
Resultado:
12
Os argumentos são diferentes e, portanto, o primeiro argumento é retornado.
Cordas
Aqui está um exemplo que compara strings:
SELECT
NULLIF( 'Gym', 'Gym' ) AS "Same",
NULLIF( 'Gym', 'Bag' ) AS "Different";
Resultado:
+------+-----------+ | Same | Different | +------+-----------+ | NULL | Gym | +------+-----------+
Datas
Aqui está um exemplo que compara datas:
SELECT
NULLIF( DATE '2045-11-25', DATE '2045-11-25' ) AS "Same",
NULLIF( DATE '2045-11-25', DATE '1990-08-15' ) AS "Different";
Resultado:
+------+------------+ | Same | Different | +------+------------+ | NULL | 2045-11-25 | +------+------------+
Expressões
NULLIF()
avalia o valor atual das expressões. Portanto, se passarmos uma expressão como esta:SELECT NULLIF( 24, 2 * 12 );
Obtemos isso:
NULL
2 multiplicado por 12 é 24, então os dois argumentos são equivalentes.
Aqui está o que acontece se alterarmos o segundo argumento:
SELECT NULLIF( 24, 3 * 12 );
Resultado:
24
O primeiro argumento é retornado.
Um exemplo de banco de dados
Suponha que executemos a seguinte consulta:
SELECT
Name,
LocalName
FROM country
WHERE Region = 'South America'
ORDER BY Name;
Resultado:
+------------------+-------------------+ | Name | LocalName | +------------------+-------------------+ | Argentina | Argentina | | Bolivia | Bolivia | | Brazil | Brasil | | Chile | Chile | | Colombia | Colombia | | Ecuador | Ecuador | | Falkland Islands | Falkland Islands | | French Guiana | Guyane française | | Guyana | Guyana | | Paraguay | Paraguay | | Peru | Perú/Piruw | | Suriname | Suriname | | Uruguay | Uruguay | | Venezuela | Venezuela | +------------------+-------------------+
Aqui, temos os nomes dos países na coluna da esquerda e o nome local do respectivo país à direita.
Vamos adicionar
NULLIF()
para uma terceira coluna de nossa consulta:SELECT
Name,
LocalName,
NULLIF(LocalName, Name) AS "Local Name if Different"
FROM country
WHERE Region = 'South America'
ORDER BY Name;
Resultado:
+------------------+-------------------+-------------------------+ | Name | LocalName | Local Name if Different | +------------------+-------------------+-------------------------+ | Argentina | Argentina | NULL | | Bolivia | Bolivia | NULL | | Brazil | Brasil | Brasil | | Chile | Chile | NULL | | Colombia | Colombia | NULL | | Ecuador | Ecuador | NULL | | Falkland Islands | Falkland Islands | NULL | | French Guiana | Guyane française | Guyane française | | Guyana | Guyana | NULL | | Paraguay | Paraguay | NULL | | Peru | Perú/Piruw | Perú/Piruw | | Suriname | Suriname | NULL | | Uruguay | Uruguay | NULL | | Venezuela | Venezuela | NULL | +------------------+-------------------+-------------------------+
Podemos ver que a terceira coluna retorna o nome local apenas se for diferente do valor no
Name
coluna. Se for o mesmo, então NULL
é devolvido. Também podemos usar
NULLIF()
para filtrar nossos resultados de consulta:SELECT
Name,
LocalName
FROM country
WHERE Region = 'South America'
AND NULLIF(LocalName, Name) IS NOT NULL
ORDER BY Name;
Resultado:
+---------------+-------------------+ | Name | LocalName | +---------------+-------------------+ | Brazil | Brasil | | French Guiana | Guyane française | | Peru | Perú/Piruw | +---------------+-------------------+
Nesse caso, retornamos apenas as linhas em que o nome local é diferente do
Name
coluna. NULLIF()
vs CASE
Como mencionado, o seguinte código:
NULLIF (V1, V2)
é equivalente ao seguinte
CASE
expressão:CASE WHEN V1=V2 THEN NULL ELSE V1 END
Portanto, é possível usar um
CASE
expressão em vez de NULLIF()
se assim desejar. O NULLIF()
função é basicamente um atalho sintático para o CASE
expressão. Assim, por exemplo, poderíamos substituir o exemplo anterior pelo seguinte:
SELECT
Name,
LocalName
FROM country
WHERE Region = 'South America'
AND (CASE WHEN LocalName = Name THEN NULL ELSE LocalName END) IS NOT NULL
ORDER BY Name;
Resultado:
+---------------+-------------------+ | Name | LocalName | +---------------+-------------------+ | Brazil | Brasil | | French Guiana | Guyane française | | Peru | Perú/Piruw | +---------------+-------------------+
No entanto, o
NULLIF()
função é muito mais concisa. Contagem de parâmetros incorreta
Passar o número errado de argumentos resulta em um erro:
SELECT NULLIF( 'One' );
Resultado no MySQL:
ERROR 1582 (42000): Incorrect parameter count in the call to native function 'NULLIF'