SQL: Why COUNT(column) Skips NULL Values
COUNT(*) counts rows, but COUNT(column) counts only non-NULL values.
The symptom
Two counts of the same table disagree. count(*) gives one
number and count(shipped_date) gives a smaller one, so a report
that should say "orders" quietly undercounts them. Neither query is broken;
they are answering different questions.
Why it happens
count(*) counts rows. count(column) counts only
rows where that column is not NULL. If a shipped date is
missing for pending or cancelled orders, those rows disappear from the
column count.
This behavior is useful when you mean "how many values are filled in," but misleading when you mean "how many rows exist."
The fix
Choose the count that matches the question: count(*) when you
mean rows, count(column) when you mean values that are filled
in. Both queries below claim to count Garden Shop orders.
select count(shipped_date) as orders
from ordersselect count(*) as orders
from orders
Garden Shop has 24 orders, and seven of them (three pending, three
processing, one cancelled) have never shipped, so their
shipped_date is NULL and
count(shipped_date) stops at 17. Naming the column you count is
what keeps this readable: count(*) as total_orders alongside
count(shipped_date) as shipped_date_filled, and
sum(case when shipped_date is null then 1 else 0 end) when you
want the gap itself as a column.
Most aggregate functions ignore NULL values. count(*) is the
special row-count form that does not inspect a specific column.
Learn more
Related
Find missing values with IS NULL.
IS NULL, COALESCE, NULLIF, and null-safe logic.
IS NULL, COALESCE, NULLIF, and null-safe equality.
Practice aggregate reports, HAVING, and answer shape.
Group or aggregate every selected column.
Keep NULLs from silently changing filter results.