Skip to content

fix(grouping): aggregate grouped columns at shallower group levels#6282

Open
ATOM00blue wants to merge 1 commit into
TanStack:mainfrom
ATOM00blue:fix/grouped-column-aggregation
Open

fix(grouping): aggregate grouped columns at shallower group levels#6282
ATOM00blue wants to merge 1 commit into
TanStack:mainfrom
ATOM00blue:fix/grouped-column-aggregation

Conversation

@ATOM00blue
Copy link
Copy Markdown

Summary

Fixes #6228 (also the long-standing #3232).

When grouping by more than one column, a grouped column was never aggregated on any group row, so it showed an empty/incorrect value at parent group levels.

Bug

Group by Department then Age, with aggregationFn: 'min' on Age. At the top-level Department group row the Age cell does not show the aggregated (min) age across the department — it shows the first leaf row's raw value (and renders blank in the demo because the grouped cell isn't treated as an aggregated cell).

Root cause

In getGroupedRowModel, the grouped row's getValue skips aggregation for any column that appears anywhere in the grouping state:

// Don't aggregate columns that are in the grouping
if (existingGrouping.includes(columnId)) {
  // return the group's own value instead of aggregating
}

A column's value is only constant across a group when that column groups the row at the current depth or a shallower (ancestor) level. A column grouped at a deeper level still varies within the current group and must be aggregated.

Fix

Compare the column's position in the grouping order against the row's depth, so only ancestor/current grouping columns short-circuit aggregation:

const groupingIndex = existingGrouping.indexOf(columnId)
if (groupingIndex > -1 && groupingIndex <= depth) {
  // ...
}

Single-column grouping is unaffected (index 0 at depth 0), so the common case behaves exactly as before.

Testing

  • Added a regression test in getGroupedRowModel.test.ts that groups by two columns and asserts the secondary grouped column is aggregated at the parent group level, while still keeping its grouping value at its own level. The test fails on main and passes with this change.
  • pnpm --filter @tanstack/table-core test:lib — all green
  • pnpm --filter @tanstack/table-core test:types — green
  • pnpm --filter @tanstack/table-core build — green
  • Added a changeset.

When grouping by multiple columns, a grouped column was never aggregated
on any group row because `getValue` skipped aggregation whenever the
column appeared anywhere in the grouping state. As a result a column that
is grouped at a deeper level showed the first leaf row's raw value at its
ancestor group rows instead of the aggregated value.

Only treat a column as a grouping value when it groups the row at the
current depth or a shallower (ancestor) level. Columns grouped at a
deeper level are aggregated as expected.
Copilot AI review requested due to automatic review settings May 22, 2026 01:46
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 22, 2026

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: f92cec4f-01d1-4de6-a624-e615ce6e9688

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Fixes grouped column aggregation so columns grouped at deeper levels are still aggregated for parent group rows (instead of showing the first leaf row’s raw value), addressing #6228 / #3232.

Changes:

  • Update grouped-row getValue logic to only short-circuit aggregation for grouping columns at the current/ancestor depth.
  • Add a regression test covering multi-column grouping where a secondary grouped column must aggregate at the parent level.
  • Add a changeset for @tanstack/table-core patch release.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
packages/table-core/src/utils/getGroupedRowModel.ts Fixes aggregation short-circuit logic by considering grouping depth.
packages/table-core/tests/getGroupedRowModel.test.ts Adds regression test for aggregating a grouped column at shallower levels.
.changeset/fix-grouped-column-aggregation.md Declares patch changeset describing the bugfix.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +95 to +100
// Don't aggregate columns that group this row at the current
// level or an ancestor level - their value is constant across
// the group. Columns grouped at a deeper level still need to
// be aggregated here.
const groupingIndex = existingGrouping.indexOf(columnId)
if (groupingIndex > -1 && groupingIndex <= depth) {
Comment on lines +8 to +17
function createPerson(firstName: string, age: number): Person {
return {
firstName,
lastName: 'Doe',
age,
visits: 0,
progress: 0,
status: 'single',
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants