COALESCE and NULLIF are ANSI-standard and behave identically in all six dialects.
-- COALESCE: first non-NULL value, useful for defaults
SELECT COALESCE(nickname, first_name, 'Unknown') AS display_name
FROM users;
-- NULLIF: returns NULL if the two arguments are equal — classic use is a safe divisor
SELECT revenue / NULLIF(unit_count, 0) AS revenue_per_unit
FROM sales;
-- unit_count = 0 -> NULLIF returns NULL -> the division returns NULL, not a divide-by-zero error
Plain = and <> never return true when either side is NULL — NULL = NULL is NULL (unknown), not true. When you need NULL to count as a comparable value (e.g. “did this column actually change?”), use IS [NOT] DISTINCT FROM:
-- PostgreSQL, SQLite 3.39+, DuckDB, BigQuery, Snowflake
SELECT * FROM t WHERE status IS DISTINCT FROM 'archived'; -- true even when status IS NULL
SELECT * FROM a JOIN b ON a.key IS NOT DISTINCT FROM b.key; -- NULL joins NULL
-- MySQL — no IS DISTINCT FROM; use the null-safe equal operator <=> instead
SELECT * FROM t WHERE NOT (status <=> 'archived');
SELECT * FROM a JOIN b ON a.key <=> b.key;
Three different tools, three different jobs.
COALESCEpicks a fallback value;NULLIFmanufactures aNULLon purpose (mainly to disarm a divisor or hide a sentinel value);IS DISTINCT FROMcompares two values while treatingNULLas an ordinary, comparable value instead of “unknown.” Mixing them up is the usual bug:NULLIF(a, b)does not tell you whetheraandbdiffer — for that, usea IS DISTINCT FROM b. MySQL is the outlier for the last one: it has noIS DISTINCT FROMsyntax at all, so<=>(available since MySQL 4.1) is the only null-safe comparison operator there.