NULLIF in PostgreSQL

Learn how to use the PostgreSQL NULLIF function to return NULL when two values are equal—commonly used to prevent division-by-zero errors and normalize empty strings to NULL.

4 min read · Back to overview

Quick Answer

NULLIF(arg1, arg2) returns NULL if the two arguments are equal, otherwise it returns arg1. It converts a specific sentinel value into NULL so downstream functions like COALESCE or division operators handle it correctly rather than raising an error.

Spin up a Postgres database in 20 seconds with Vela.

Try Vela Sandbox

NULLIF(argument_1, argument_2) returns NULL when the two arguments are equal, and returns argument_1 otherwise. It is the inverse of COALESCE: instead of replacing NULL with a value, NULLIF converts a specific value back into NULL. The two functions are often combined to handle both real NULL values and sentinel values like empty strings or zeros.

Syntax

NULLIF(argument_1, argument_2)

Basic scalar examples:

SELECT NULLIF(1, 1);    -- returns NULL  (arguments are equal)
SELECT NULLIF(1, 0);    -- returns 1     (arguments differ)
SELECT NULLIF('A', 'B'); -- returns 'A'  (arguments differ)
SELECT NULLIF('', '');   -- returns NULL (empty strings match)

Practical Example

An events table where the venue column may be stored as either NULL or an empty string—semantically both mean “no venue assigned”:

CREATE TABLE events (
  id         SERIAL PRIMARY KEY,
  title      VARCHAR(200) NOT NULL,
  venue      VARCHAR(200),    -- may be NULL or ''
  description TEXT
);

INSERT INTO events (title, venue, description) VALUES
  ('Product Launch',   'Convention Center',   'Annual product reveal'),
  ('Team Offsite',     '',                    'Remote team gathering'),
  ('Board Meeting',    NULL,                  'Quarterly review'),
  ('Dev Conference',   'Tech Hub',            'Engineering summit');

-- Without NULLIF: empty string '' and NULL are treated differently
SELECT id, title, COALESCE(venue, 'TBD') AS display_venue
FROM events;
 id |      title      |      display_venue
----+-----------------+--------------------
  1 | Product Launch  | Convention Center
  2 | Team Offsite    |                    -- empty string slips through
  3 | Board Meeting   | TBD
  4 | Dev Conference  | Tech Hub

Use NULLIF to treat '' the same as NULL:

SELECT
  id,
  title,
  COALESCE(NULLIF(venue, ''), 'TBD') AS display_venue
FROM events;
 id |      title      |    display_venue
----+-----------------+------------------
  1 | Product Launch  | Convention Center
  2 | Team Offsite    | TBD
  3 | Board Meeting   | TBD
  4 | Dev Conference  | Tech Hub

Preventing Division-by-Zero

Dividing by zero raises an error in PostgreSQL. Wrap the denominator with NULLIF(..., 0) to convert zero into NULL, returning NULL rather than failing:

CREATE TABLE orders (
  id          SERIAL PRIMARY KEY,
  product_id  INTEGER NOT NULL,
  quantity    INTEGER NOT NULL,
  total_cost  NUMERIC(10, 2) NOT NULL
);

INSERT INTO orders (product_id, quantity, total_cost) VALUES
  (1, 10, 250.00),
  (2,  0,   0.00),   -- zero quantity edge case
  (3,  5, 125.00);

-- Safe unit cost calculation—returns NULL instead of error when quantity = 0
SELECT
  id,
  product_id,
  quantity,
  total_cost,
  ROUND(total_cost / NULLIF(quantity, 0), 2) AS unit_cost
FROM orders;
 id | product_id | quantity | total_cost | unit_cost
----+------------+----------+------------+-----------
  1 |          1 |       10 |     250.00 |     25.00
  2 |          2 |        0 |       0.00 |      NULL
  3 |          3 |        5 |     125.00 |     25.00

Inspect which rows would be affected without the guard:

SELECT id FROM orders WHERE NULLIF(quantity, 0) IS NULL;

Testing with Vela

Data cleaning code that depends on NULLIF is sensitive to the actual mix of NULL, empty string, and zero values in production. Clone a production snapshot to a Vela branch to validate your NULLIF / COALESCE chains against real column distributions before rolling out schema changes or ETL updates.

Production Tips

  • The canonical null-safe string pattern is COALESCE(NULLIF(col, ''), fallback)—it handles both actual NULL and empty string in one expression.
  • Guard every division expression with NULLIF(denominator, 0), especially in aggregations over user-supplied data where zero denominators are plausible.
  • NULLIF evaluates argument_1 twice internally. This is rarely a concern but matters if the argument is a function with side effects.
  • Both arguments must be of compatible types. Use explicit CAST when combining a text column with an integer sentinel to avoid type errors.
  • Combine with EXPLAIN (ANALYZE) to verify that null guards in WHERE clauses do not accidentally disable index scans on frequently queried columns.

Continue in Conditional Expressions & Operators: CAST.

Related in this section: CASE · COALESCE · ISNULL

Frequently Asked Questions

What does NULLIF do in PostgreSQL?
NULLIF(a, b) returns NULL when a equals b, otherwise it returns a. It converts a known sentinel value back into NULL so null-handling functions like COALESCE can treat it the same as a genuinely missing value.
How is NULLIF different from COALESCE?
They are complementary opposites. COALESCE replaces NULL with a non-null fallback value. NULLIF converts a specific non-null value back into NULL. The combination COALESCE(NULLIF(col, ''), fallback) handles both actual NULLs and empty strings in one step.
How do I prevent division by zero in PostgreSQL?
Wrap the denominator in NULLIF(denominator, 0). When the denominator is zero, NULLIF converts it to NULL, and any arithmetic involving NULL returns NULL rather than raising a division-by-zero error.
Can NULLIF compare values of different types?
Both arguments must be of compatible types. PostgreSQL applies standard type-coercion rules to resolve a common type. If the types are incompatible it raises a type error—add an explicit cast to one argument to resolve it.
What is the safest way to use NULLIF in production?
Always combine NULLIF with COALESCE when you want a non-null fallback: COALESCE(NULLIF(col, sentinel), default). Wrap every division denominator with NULLIF(denominator, 0) to avoid runtime errors on unexpected zero values. Test with production data on a branch before deploying.