Aggregation & GROUP BY
Concept  ·  SQL & Querying

SUM of no rows (or all-NULL) returns NULL, not 0 — COALESCE(SUM(...),0) at the bar.

SUM answers 'what do these rows add to?' — with no rows there is nothing to add, and SQL returns NULL rather than inventing 0. The damage is downstream: NULL + 500 is NULL, a payroll line vanishes, a chart gaps. COALESCE(SUM(x), 0) is the honest spelling of 'treat absence as zero' — a decision, made visible. COUNT is the exception: it returns 0, because 'how many' always has an answer.

See it break
artists
artist
Mo
Vee
sessions
artistminutes
Mo90
Mo45
The trap
SELECT
  a.artist,
  SUM(s.minutes)AS total
FROM
  artists a
  LEFT JOIN sessions s ON s.artist = a.artist
GROUP BY
  a.artist
ORDER BY
  a.artist;
The fix
SELECT
  a.artist,
  COALESCE(SUM(s.minutes), 0) AS total
FROM
  artists a
  LEFT JOIN sessions s ON s.artist = a.artist
GROUP BY
  a.artist
ORDER BY
  a.artist;
INPUTYour queryThe fix
Mo135135
VeeNULL0

The invoice run reads NULL for the new artist instead of 0 minutes — SUM over zero rows returns NULL, and downstream the payroll line blanks out.

The rule

Wrap the aggregate in COALESCE(SUM(...), 0), or keep NULL deliberately and let the consumer tell 'no activity' from 'zero'.

Shows up elsewhere
COUNT(*) vs COUNT(col) vs COUNT(DISTINCT col)NULL propagates in expressions
Try one →Prove it in practice →