Skip to the solution
MediumDSA14 min read

How does SQL handle NULL values?

940 views

The problem

Question presented to candidate: "Some of our employees have no bonus recorded and some have no manager. Explain what NULL actually means in SQL, why WHERE bonus = NULL returns nothing, and which other places in a query NULL quietly changes the result."

What a strong answer should cover:

  • NULL means unknown or missing, not zero and not an empty string; it is a marker, not a value
  • Three-valued logic: comparisons with NULL give UNKNOWN, and WHERE, ON and HAVING keep only rows that are TRUE, so = NULL matches nothing; use IS NULL / IS NOT NULL or the null-safe IS [NOT] DISTINCT FROM
  • NULL propagates through arithmetic and || concatenation; NOT (UNKNOWN) is still UNKNOWN, so a filter and its negation can both miss a row
  • Where NULLs group together instead: GROUP BY, DISTINCT and set operations put all NULLs in one bucket; UNIQUE allows many NULLs (PostgreSQL 15 added NULLS NOT DISTINCT)
  • Engine details: NULL sorts first in SQLite and last in PostgreSQL ascending (NULLS FIRST/LAST), Oracle treats '' as NULL, aggregates skip NULLs, and NOT IN with a NULL in the list returns no rows

Code / implementation expected: Optional β€” show = NULL vs IS NULL and one case where a filter and its negation together lose rows.

Schema used by the examples:

  • null

Try it yourself

Sketch your approach before you read the solution. That is what the interview tests.

Stuck? Get a hint.

A short nudge toward the approach. It will not give the answer away.

Solution

The solution is hidden so you can try first

14 min read Β· 12 sections

Run the code

Edit the query and run it against the tables for this question.

SQL= NULL matches nothing; IS NULL and IS NOT NULL do the job
SQLA filter and its NOT together still miss the NULL rows
SQLNULL spreads through expressions, groups together, and sorts first in SQLite
PostgreSQL: the three-valued truth table with real booleans
SELECT v.a, v.b,
       v.a AND v.b AS a_and_b,
       v.a OR v.b AS a_or_b,
       NOT v.a AS not_a,
       (v.a = v.b) IS NULL AS eq_is_unknown,
       v.a IS NOT DISTINCT FROM v.b AS null_safe_eq
FROM (VALUES (true, NULL::boolean),
             (false, NULL::boolean),
             (NULL::boolean, NULL::boolean)) AS v(a, b);

Discussion

Other approaches, follow-ups and how it went in real interviews.

Sign in to join the discussion.

No comments yet. Share how you would answer it.

Question 32 of 82 in SQL

Keep your momentum going.

Mark this question solved to track your progress, then take the next one while it is fresh.

All SQL questions
Up nextMedium

What is a view and a materialized view?

Continue