← Home ← Codex ← DEBT
Browse by Category
+ added · updated 7d
← Back to glossary

MySQL NULL Handling

database Beginner
debt(d5/e1/b3/t7)
d5 Detectability Operational debt — how invisible misuse is to your safety net

Closest to 'specialist tool catches it' (d5). The detection_hints list semgrep as the tool, with an automated pattern match for `WHERE column = NULL` or `WHERE column != NULL`. Semgrep is a specialist SAST tool rather than a default linter or compiler, so d5 fits exactly. The bug is silent at runtime (returns zero rows) making it invisible without tooling.

e1 Effort Remediation debt — work required to fix once spotted

Closest to 'one-line patch or single-call swap' (e1). The quick_fix is a direct substitution: replace `= NULL` with `IS NULL` or wrap in `COALESCE()`. This is a mechanical, localised text change with no structural refactoring required.

b3 Burden Structural debt — long-term weight of choosing wrong

Closest to 'localised tax' (b3). The issue applies across web and cli contexts, but each occurrence is a self-contained query fix. It doesn't shape architectural decisions or impose a persistent productivity tax across many work streams — each fix is local to its query or DAL method.

t7 Trap Cognitive debt — how counter-intuitive correct behaviour is

Closest to 'serious trap (contradicts how a similar concept works elsewhere)' (t7). The misconception field states the canonical wrong belief: developers expect `NULL = NULL` to be true, as equality works everywhere else in programming. This directly contradicts universal equality semantics, making it a serious cognitive trap. It is documented and well-known but routinely tripped over because the intuition from other languages is strongly wrong here.

About DEBT scoring →

Also Known As

SQL NULL IS NULL MySQL COALESCE MySQL NULL comparison SQL

TL;DR

NULL in SQL represents an unknown value — it is not zero, not empty string, and comparisons with = NULL are always false.

Explanation

NULL = NULL evaluates to NULL (not true) — use IS NULL and IS NOT NULL for comparisons. NULL in aggregate functions is ignored by COUNT(column) but counted by COUNT(*). NULL values sort last in ORDER BY ASC (MySQL-specific — other databases differ). COALESCE(val, default) returns the first non-NULL value. IFNULL(val, default) is MySQL-specific. Columns with frequent NULL values have reduced index efficiency.

Watch Out

NULL propagates through all arithmetic — NULL + 5 = NULL, NULL || 'text' = NULL. Always handle NULLs explicitly.

Common Misconception

NULL = NULL is true. NULL compared to anything — including another NULL — always returns NULL (unknown). Use IS NULL for null checks.

Why It Matters

Using = NULL in WHERE clauses silently matches nothing — a common source of 'query returns no rows' bugs. NULL propagates through arithmetic — NULL + 5 = NULL.

Common Mistakes

  • Writing WHERE column = NULL instead of WHERE column IS NULL — matches zero rows.
  • Expecting COUNT(column) to count NULL rows — it doesn't; use COUNT(*) instead.
  • Sorting by a nullable column and not accounting for NULLs appearing last (ASC) or first (DESC).

Avoid When

  • Do not use nullable columns for data that is always required — use NOT NULL with a sensible DEFAULT instead.
  • Do not rely on IFNULL() for portability — use COALESCE() which is SQL standard.

When To Use

  • Use IS NULL / IS NOT NULL for all NULL comparisons — never use = NULL.
  • Use COALESCE(column, default) to substitute a fallback for NULL values in SELECT.

Code Examples

✗ Vulnerable
-- Wrong: WHERE column = NULL always returns 0 rows
SELECT * FROM users WHERE deleted_at = NULL; -- always empty

-- Wrong: COUNT(nullable_column) skips NULLs
SELECT COUNT(deleted_at) FROM users; -- counts only non-NULL deleted_at
✓ Fixed
-- Correct NULL comparison
SELECT * FROM users WHERE deleted_at IS NULL;
SELECT * FROM users WHERE deleted_at IS NOT NULL;

-- COALESCE for default values
SELECT id, COALESCE(display_name, email) AS name FROM users;

-- COUNT distinction
SELECT COUNT(*) as total, COUNT(email) as with_email FROM users;

Added 31 Mar 2026
Views 55
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings T 0 pings W 0 pings T 0 pings F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 2 pings F 1 ping S 0 pings S 1 ping M 0 pings T 0 pings W 0 pings T 1 ping F 2 pings S 0 pings S 0 pings M 0 pings T 1 ping W 0 pings T 0 pings F 1 ping S 0 pings S 1 ping M 0 pings T 0 pings W
No pings yet today
No pings yesterday
ChatGPT 19 Google 4 Perplexity 3 Unknown AI 3 Ahrefs 2 Meta AI 2 SEMrush 1
crawler 31 crawler_json 2 pre-tracking 1
DEV INTEL Tools & Severity
⚙ Fix effort: Low
⚡ Quick Fix
Use IS NULL / IS NOT NULL for comparisons — use COALESCE() to provide defaults for nullable columns
📦 Applies To
web cli
🔗 Prerequisites
🔍 Detection Hints
WHERE column = NULL or WHERE column != NULL in SQL strings
Auto-detectable: ✓ Yes semgrep
⚠ Related Problems
🤖 AI Agent
Confidence: High False Positives: Low ✓ Auto-fixable Fix: Low Context: Line

✓ schema.org compliant