Per-group reporting
Summarize activity by geography, category, or another model field.
Prisma · Function
Prisma Client groupBy() groups records by one or more fields and calculates aggregates for each group. It supports pre-group filtering with where, post-group filtering with having, and ordering grouped results.
Call groupBy() on a Prisma Client model with one or more fields in by. Prisma filters matching records with where, forms groups, calculates requested aggregates such as _count or _avg, and can filter completed groups with having or sort them with orderBy.
prisma.<model>.groupBy({ by, where?, having?, orderBy?, take?, skip?, _count?, _avg?, _sum?, _min?, _max? })| Name | Type | Description |
|---|---|---|
by | string | string[] | Fields whose values define the groups; provide one or more model field names. |
where | ModelWhereInput | Filters records before grouping and aggregation. |
_count, _avg, _min, _max, _sum | aggregate selections | Requests aggregate values for each group, including count, average, minimum, maximum, or sum. |
having | ModelScalarWhereWithAggregatesInput | Filters complete groups using field or aggregate conditions. |
orderBy | OrderByWithAggregationInput | OrderByWithAggregationInput[] | Controls the ordering of grouped rows, including supported aggregate ordering. |
take | number | Limits the number of grouped rows returned. |
skip | number | Skips grouped rows before returning results. |
An array containing one result object per group, with the grouping fields and requested aggregate values.
by to create groups from one field or a combination of fields.by: 'fieldName' is a supported shorthand.select is not supported for this operation; fields listed in by are returned automatically.where prevents excluded records from contributing to aggregates.having for aggregate-based group filtering, not where.const groupedUsers = await prisma.user.groupBy({
by: ['country'],
where: { email: { endsWith: 'prisma.io' } },
_count: { _all: true },
_avg: { profileViews: true },
orderBy: { _avg: { profileViews: 'desc' } },
});
console.log(groupedUsers);Groups matching users by country, then returns each country's row count and average profile views.
Summarize activity by geography, category, or another model field.
Find averages, totals, extrema, or row counts for each group.
Return only groups meeting an aggregate threshold.
groupBy() do?groupBy() groups records by the fields in by and computes requested aggregates for each group. For example, _sum, _avg, _min, _max, and _count can be used to summarize grouped data.
Follow-up: How would you avoid aggregating unwanted rows? Use where, because it filters records before grouping; use having only when filtering completed groups by aggregate values.
where and having in groupBy()?where filters individual records before Prisma creates groups. having filters whole groups afterward and can compare aggregate values such as an average or sum.
Follow-up: Why can having be more expensive than where? It operates after grouping, so the database may need to form groups from more input rows first.
The fields named in by are returned automatically, and Prisma does not allow select with groupBy(). A single grouping field can use the shorthand string form instead of an array.
Follow-up: How can you order grouped results? Add orderBy, including aggregate ordering such as ordering by a count or average.
aggregate()count()findMany()distincthavingorderBy