Table.Group()
Learn how Table.Group aggregates rows into per-group summaries, the M equivalent of SQL's GROUP BY.
Table.Group()
Table.Group() groups a table's rows by one or more columns and computes an aggregation per group — the M equivalent of SQL's GROUP BY.
Table.Group(
table as table,
key as any,
aggregatedColumns as list
) as tableBasic Example
#"Grouped Rows" = Table.Group(
Source, {"Category"},
{{"TotalSales", each List.Sum([SalesAmount]), type number}}
)Source (one row per order) Grouped Rows (one row per category)
Category | SalesAmount Category | TotalSales
Bikes | 500 Bikes | 1,250
Bikes | 750 --> Accessories | 300
Accessories | 300Each aggregated column is defined as a triple: a name for the result column, a function run against each group's rows, and (optionally) the result type.
Multiple Aggregations at Once
#"Grouped Rows" = Table.Group(
Source, {"Category"},
{
{"TotalSales", each List.Sum([SalesAmount]), type number},
{"OrderCount", each Table.RowCount(_), Int64.Type},
{"AvgSale", each List.Average([SalesAmount]), type number}
}
)The underscore _ inside an aggregation function refers to the current group — a table containing just that group's rows — which is what Table.RowCount(_) counts.
Grouping by Multiple Columns
#"Grouped Rows" = Table.Group(
Source, {"Category", "Region"},
{{"TotalSales", each List.Sum([SalesAmount]), type number}}
)Category | Region | TotalSales
Bikes | West | 800
Bikes | East | 450
Accessories | West | 300One output row per unique combination of the grouping columns — the same shape SQL's GROUP BY Category, Region would produce.
Table.Group vs. the Group By Button
The Group By button in the Power Query ribbon generates exactly this function — Table.Group() is what's actually running underneath, whether it was written by hand or generated by the UI.
| UI (Group By button) | Hand-written Table.Group | |
|---|---|---|
| Speed to write | Faster for simple, single-aggregation grouping | Faster once several aggregations are needed at once |
| Flexibility | Limited to the dialog's supported aggregations | Any M expression, including custom logic beyond sum/count/average |
Common Mistakes
Forgetting the Result Type
Omitting the third element of each aggregation triple still works, but leaves the result column typed as any — worth adding explicitly (type number, Int64.Type) so downstream steps don't need an extra Table.TransformColumnTypes just to fix it.
Referencing the Wrong Table Inside an Aggregation
Inside an aggregation function, _ refers to the current group, not the original source table — using the original table's name instead of _ aggregates over everything, not just the current group's rows.
Grouping Before Cleaning the Data
Grouping locks in whatever's in the key columns at that point — a typo or inconsistent casing in a grouping column (e.g. "Bikes" vs "bikes") produces two separate groups instead of one. Clean and type the grouping columns before grouping, not after.
Best Practices
- Add an explicit result type to every aggregation, rather than leaving it as
any. - Use
_(the current group) inside aggregation functions, not the original source table. - Clean and type grouping columns before grouping — a mistake here silently produces extra groups instead of an error.
- Prefer
Table.Groupdirectly (over the UI) once more than one or two aggregations are needed — it's easier to read and maintain as a single step.
Next Steps
Continue learning Power Query: