Grouping starts from visible input rows.

highlighted = computed this step

Start with base rows

Grouping starts from visible input rows, not from hidden summary labels.

rows first\text{rows first}

Show the rows

The table has 5 rows and will form 3 groups by kind.

rows=5\text{rows}=5

Grouping examples are tiny finite table transforms; SQL dialects, NULLs, AVG/rounding, planner behavior, indexes, performance, and product behavior are out of scope.

Start with base rows: base rowssourceRowidkindqty01book212game123book334game445tool1 group by columnscolumnkind aggregate specsopcolumnascount_rowsrowsn group bucketskeysourceRowsrowCount[book][0, 2]2[game][1, 3]2[tool][4]1 aggregate rowskeyn[book]2[game]2[tool]1 having keep/dropkeystatusreason[book]keepno_having[game]keepno_having[tool]keepno_having output rowskeyn[book]2[game]2[tool]1 group factsfactvaluerowCount5groupByColumnCount1groupCount3aggregateCount1outputGroupCount3havingnonehiddenGroupsno

Read sourceRow

Each input row keeps a sourceRow so the later buckets can point back to it.

source rows are visible\text{source rows are visible}

Summary

Every displayed count later in the book is recomputed from these rows.

recomputed from rows\text{recomputed from rows}