The essentials

Quick reference

One focused task per row. Jump to the related section for complete, working examples.

UseSyntaxExamples
Test for nullWHERE deleted_at IS NULLView examples
Test for a valueWHERE email IS NOT NULLView examples
Null-safe inequalityold_value IS DISTINCT FROM new_valueView examples
Null-safe equalityleft_value IS NOT DISTINCT FROM right_valueView examples
First non-null valueCOALESCE(display_name, username, 'Anonymous')View examples
Convert equality to nullNULLIF(denominator, 0)View examples
Searched CASECASE WHEN score >= 90 THEN 'A' WHEN score >= 80 THEN 'B' ELSE 'C' ENDView examples
Simple CASECASE status WHEN 'open' THEN 1 WHEN 'closed' THEN 0 ELSE NULL ENDView examples
Count non-null valuesCOUNT(completed_at)View examples
Count all rowsCOUNT(*)View examples
Place nulls lastORDER BY priority DESC NULLS LASTView examples

NULL represents an unknown or absent value, not an empty string or zero. Comparisons involving NULL usually produce unknown, and WHERE retains only true rows. Use null-specific predicates and make fallback, equality, aggregation, and ordering behavior explicit.

Step by step

Detailed examples

01

Filter three-valued logic intentionally

`value = NULL` is unknown, never true; use IS NULL. AND, OR, and NOT propagate unknown according to three-valued logic, and CHECK accepts true or unknown unless a separate NOT NULL constraint rejects absence. Parenthesize mixed conditions.

Select active records without a deletion timestamp
WITH items (id, deleted_at) AS (VALUES (1, NULL::timestamp), (2, TIMESTAMP '2026-01-01'))
SELECT id FROM items WHERE deleted_at IS NULL ORDER BY id;
Output
id
--
1
Back to quick reference ↑
02

Compare nullable values with boolean results

Ordinary equality and inequality return unknown when either side is null. IS DISTINCT FROM and IS NOT DISTINCT FROM always return true or false and are useful for change detection, joins, and tests where null should behave as a value.

Detect nullable changes
SELECT NULL IS DISTINCT FROM NULL AS changed_a,
       NULL IS DISTINCT FROM 3 AS changed_b,
       3 IS NOT DISTINCT FROM 3 AS equal_c;
Output
changed_a | changed_b | equal_c
----------+-----------+--------
false     | true      | true
Back to quick reference ↑
03

Fallback or neutralize values lazily

COALESCE evaluates only until it finds a non-null result and requires compatible result types. NULLIF is useful for turning a sentinel or zero denominator into null. A fallback changes presentation or calculation semantics; it does not repair missing source data.

Display a label and avoid division by zero
SELECT COALESCE(NULL, 'guest') AS label,
       10 / NULLIF(0, 0) AS ratio;
Output
label | ratio
------+------
guest | NULL
Back to quick reference ↑
04

Return one typed result from ordered branches

Searched CASE tests arbitrary conditions; simple CASE compares one expression to values. The first matching branch wins, so put specific conditions first. CASE normally evaluates only the chosen result, but planning-time constant folding can still expose invalid constant expressions.

Bucket scores
WITH scores(value) AS (VALUES (95), (84), (NULL))
SELECT value, CASE WHEN value >= 90 THEN 'A' WHEN value >= 80 THEN 'B' ELSE 'ungraded' END AS grade
FROM scores ORDER BY value NULLS LAST;
Output
value | grade
------+---------
84    | B
95    | A
NULL  | ungraded
Back to quick reference ↑
05

Specify null behavior in summaries and sort order

Most aggregates ignore null inputs; COUNT(*) counts rows and COUNT(expression) counts non-null results. An aggregate over no qualifying inputs often returns null, except COUNT. PostgreSQL defaults null placement based on direction, so state NULLS FIRST or LAST when presentation matters.

Compare row and value counts
WITH values(value) AS (VALUES (1), (NULL), (3))
SELECT COUNT(*) AS rows, COUNT(value) AS known, AVG(value) AS average FROM values;
Output
rows | known | average
-----+-------+--------
3    | 2     | 2.0000
Back to quick reference ↑

Sources and further reading

References

Authoritative documentation used to verify and expand this cheat sheet.

  1. PostgreSQL Global Development GroupPostgreSQL: Comparison Functions and Operatorspostgresql.org
  2. PostgreSQL Global Development GroupPostgreSQL: Conditional Expressionspostgresql.org
  3. PostgreSQL Global Development GroupPostgreSQL: Aggregate Functionspostgresql.org

Help us improve

Found a typo or missing example?

Tell us what would make this cheat sheet clearer, more complete, or more useful.

Share feedback