SQL Semantics
GROUP BY
GROUP BY forms groups and treats NULL as its own group.
GROUP BY forms groups
GROUP BY partitions rows by the grouping value and computes aggregates per group. NULL forms its own group instead of disappearing. Note: the result table shows the groups.
Grouping grades
The recomputed group count is 4. Note: the missing grade appears as its own rendered group.
SQL bag/multiset + three-valued NULL logic, deterministic but surprising; tiny finite tables; no engine/perf claims. Set algebra is Book 1.
The NULL group is real
The NULL group has COUNT star 1 and COUNT grade 0. The duplicated-grade group has COUNT star 2. Note: grouping keeps the NULL bucket even though COUNT grade skips its NULL value.
SQL bag/multiset + three-valued NULL logic, deterministic but surprising; tiny finite tables; no engine/perf claims. Set algebra is Book 1.
Summary
GROUP BY treats NULL as a grouping value for grouping purposes. Note: bag and NULL behavior are here; set algebra was Book One.