Data Analysis

Google Sheets QUERY Cannot Group Without Agg Fix

Marc SeanJune 13, 20265 min read

Why the Error Fires

Google's QUERY function runs on the Google Visualization API query language, which follows strict SQL-like rules. The documentation states: "When using GROUP BY, each column in the SELECT clause must either be listed in the GROUP BY clause, or use an aggregation function."

No ambiguity, no exceptions. Every column is either a dimension (listed in GROUP BY) or a measure (wrapped in an aggregate). The moment you mix those roles, QUERY stops with cannot group without agg.

Here's a concrete example. You have a Revenue tab with columns: Date (A), Region (B), SKU (C), Revenue (D), COGS (E). You want revenue by region:

=QUERY('Revenue'!A:E, "SELECT B, C, SUM(D) GROUP BY B", 1)

This returns the error because column C (SKU) appears in SELECT but isn't in GROUP BY and isn't aggregated. Two valid fixes:

Option 1 - Add SKU to GROUP BY (returns one row per region-SKU pair):

=QUERY('Revenue'!A:E, "SELECT B, C, SUM(D) GROUP BY B, C", 1)

Option 2 - Drop SKU from SELECT (returns one row per region):

=QUERY('Revenue'!A:E, "SELECT B, SUM(D) GROUP BY B", 1)

Which fix is right depends on the output you need, not on QUERY syntax. If you want revenue by region alone, drop C. If you want revenue by region-SKU, keep C and add it to GROUP BY.

The Column Audit Pattern

For a board pack query with 6+ columns, audit every SELECT column before running. Here's a Q2 actuals pull that groups correctly:

=QUERY(
  'Revenue'!A:F,
  "SELECT B, SUM(D), SUM(E), SUM(D)-SUM(E)
   WHERE A >= date '2026-04-01' AND A <= date '2026-06-30'
   GROUP BY B
   LABEL SUM(D) 'Revenue', SUM(E) 'COGS', SUM(D)-SUM(E) 'Gross Profit'",
  1
)

Region (B) is the dimension - it goes in GROUP BY. Revenue, COGS, and Gross Profit are measures - every one is wrapped in SUM() or expressed as a combination of aggregates. The expression SUM(D)-SUM(E) works precisely because both components are aggregated. The result per group is a single value, which is all QUERY requires.

QUERY GROUP BY vs. SUMIFS: Choosing the Right Tool

QUERY's GROUP BY is clean for single-tab aggregation. For multi-tab financial models, SUMIFS usually wins. Here's the honest comparison:

ScenarioQUERY GROUP BYSUMIFS / SUMPRODUCT
Single-tab aggregationClean, SQL-like syntaxMore verbose
Cross-tab referencesNot supported nativelyNative, reliable
Dynamic date from Assumptions tabString concat required">=" & Assumptions!$B$3
Multiple filter conditionsWHERE clauseStacked SUMIFS criteria
Datasets over 10,000 rowsSlower on recalcFaster
Unknown set of dimension valuesReturns all rows automaticallyRequires hardcoded criteria
Debugging grouping errorscannot group without agg#VALUE! on bad ranges

If your quarterly board pack pulls actuals where the date range lives in Assumptions!$B$3:$B$4 and revenue sits in 'P&L'!C:C, SUMIFS handles it without QUERY's string concatenation workaround:

=SUMIFS(
  'P&L'!C:C,
  'P&L'!B:B, ">=" & Assumptions!$B$3,
  'P&L'!B:B, "<=" & Assumptions!$B$4,
  'P&L'!D:D, Returns!$A2
)

QUERY can't directly reference Assumptions!$B$3 inside the query string. You'd need to concatenate it as a text value, which breaks on date formatting and produces errors that look unrelated to the original problem. SUMIFS takes the cell reference natively.

When QUERY GROUP BY Is Worth It

QUERY earns its place when you don't know the distinct values in advance. If you have 14 active SKUs and need contribution margin by SKU for a gross margin analysis (38.5% target, current blended at 34.1%), QUERY returns all 14 rows without hardcoding:

=QUERY(
  'Sales'!A:G,
  "SELECT C, SUM(D), SUM(E), (SUM(D)-SUM(E))/SUM(D)
   GROUP BY C
   ORDER BY (SUM(D)-SUM(E))/SUM(D) DESC
   LABEL C 'SKU', SUM(D) 'Revenue', SUM(E) 'COGS'",
  1
)

The margin expression (SUM(D)-SUM(E))/SUM(D) doesn't trigger a grouping error because every component is aggregated. One value per group, every time. SUMIFS would require one hardcoded row per SKU, which breaks the moment a new SKU appears in the data.

The Non-Obvious Edge Cases

Labels: The LABEL clause doesn't cause grouping errors itself, but mislabeling an already-broken SELECT column shifts the error message in ways that make it look like a label problem. Always audit SELECT and GROUP BY before touching LABEL.

COUNT() vs. COUNT(column): COUNT(D) counts non-null values in column D. COUNT() with no argument isn't valid in Google's implementation. As of June 2026, this sometimes surfaces as cannot group without agg rather than a more specific error, which wastes debugging time. If you're seeing the error and the grouping looks right, check your COUNT syntax.

Expressions across groups: SUM(D)/COUNT(D) is valid (both components are aggregated). SUM(D)/D is not (D in the denominator is unaggregated). The rule applies to every term in any expression, not just standalone column references.

ModelMonkey catches this class of QUERY error before it writes to the sheet and suggests the corrected formula directly in the sidebar - useful when you're 6 levels deep in a multi-tab model and the error message alone doesn't identify which column is the offender.

The cannot group without agg error means one or more SELECT columns aren't aggregated and aren't in GROUP BY. Audit every column: dimensions go in GROUP BY, measures get SUM/AVG/COUNT/MAX/MIN. For cross-tab work or dynamic date ranges from an Assumptions tab, SUMIFS handles what QUERY can't. For dynamic dimension sets where you don't know the values in advance, QUERY's GROUP BY is the cleaner choice.


Frequently Asked Questions