SQL NULLIF() Explained

Most major RDBMSs support the NULLIF() operator, which returns NULL if both of its arguments are equivalent. If the arguments not equivalent, NULLIF() returns the first argument.

NULLIF() is a SQL-standard feature (it’s included in the ISO/IEC 9075 specification).

Syntax

The syntax goes like this:

NULLIF (V1, V2)

This is equivalent to the following CASE expression:

CASE WHEN V1=V2 THEN NULL ELSE V1 END

Example

Here’s an example to demonstrate:

SELECT NULLIF( 12, 12 );

Result:

NULL

In this case, both arguments are identical and so the result is NULL.

Depending on your RDBMS, the actual output for NULL values may be different. For example, when using psql (for PostgreSQL), the empty string is output by default whenever a NULL value is returned (although this can be changed). It’s the same with SQLite (and this can also be changed).

When the Arguments are Not Equivalent

Here’s what happens when the arguments are not equivalent:

SELECT NULLIF( 12, 13 );

Result:

12

The arguments are different and so the first argument is returned.

Strings

Here’s an example that compares strings:

SELECT 
    NULLIF( 'Gym', 'Gym' ) AS "Same",
    NULLIF( 'Gym', 'Bag' ) AS "Different";

Result:

+------+-----------+
| Same | Different |
+------+-----------+
| NULL | Gym       |
+------+-----------+

Dates

Here’s an example that compares dates:

SELECT 
    NULLIF( DATE '2045-11-25', DATE '2045-11-25' ) AS "Same",
    NULLIF( DATE '2045-11-25', DATE '1990-08-15' ) AS "Different";

Result:

+------+------------+
| Same | Different  |
+------+------------+
| NULL | 2045-11-25 |
+------+------------+

Expressions

NULLIF() evaluates the current value of the expressions. Therefore, if we pass an expression like this:

SELECT NULLIF( 24, 2 * 12 );

We get this:

NULL

2 multiplied by 12 is 24, and so the two arguments are equivalent.

Here’s what happens if we change the second argument:

SELECT NULLIF( 24, 3 * 12 );

Result:

24

The first argument is returned.

A Database Example

Suppose we run the following query:

SELECT 
    Name,
    LocalName
FROM country 
WHERE Region = 'South America'
ORDER BY Name;

Result:

+------------------+-------------------+
| 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         |
+------------------+-------------------+

Here, we have country names in the left column, and the local name for the respective country in the right.

Let’s add NULLIF() to a third column of our query:

SELECT
    Name,
    LocalName,
    NULLIF(LocalName, Name) AS "Local Name if Different"
FROM country 
WHERE Region = 'South America'
ORDER BY Name;

Result:

+------------------+-------------------+-------------------------+
| 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                    |
+------------------+-------------------+-------------------------+

We can see that the third column returns the local name only if it’s different to the value in the Name column. If it’s the same, then NULL is returned.

We can also use NULLIF() to filter our query results:

SELECT 
    Name,
    LocalName
FROM country 
WHERE Region = 'South America'
AND NULLIF(LocalName, Name) IS NOT NULL
ORDER BY Name;

Result:

+---------------+-------------------+
| Name          | LocalName         |
+---------------+-------------------+
| Brazil        | Brasil            |
| French Guiana | Guyane française  |
| Peru          | Perú/Piruw        |
+---------------+-------------------+

In this case, we returned only those rows where the local name is different to the Name column.

NULLIF() vs CASE

As mentioned, the following code:

NULLIF (V1, V2)

is equivalent to the following CASE expression:

CASE WHEN V1=V2 THEN NULL ELSE V1 END

So it is possible to use a CASE expression instead of NULLIF() if so desired. The NULLIF() function is basically a syntactical shortcut for the CASE expression.

So for example, we could replace the previous example with the following:

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;

Result:

+---------------+-------------------+
| Name          | LocalName         |
+---------------+-------------------+
| Brazil        | Brasil            |
| French Guiana | Guyane française  |
| Peru          | Perú/Piruw        |
+---------------+-------------------+

However, the NULLIF() function is much more concise.

Incorrect Parameter Count

Passing the wrong number of arguments, results in an error:

SELECT NULLIF( 'One' );

Result in MySQL:

ERROR 1582 (42000): Incorrect parameter count in the call to native function 'NULLIF'