zanith

Aggregates & GroupBy

Count records, sum values, calculate averages — with GROUP BY for analytics queries. All built into the query builder, not raw SQL.

Why aggregates?

"How many posts does each author have?" "What's the total revenue per month?" These questions require aggregation — combining multiple rows into summary values. Without aggregates, you'd either write raw SQL or fetch all rows and compute in JavaScript. Zanith lets you express these queries naturally in the builder.

Available functions

TS
import { count, countDistinct, sum, avg, min, max } from 'zanith';
FunctionSQL outputUse case
count()COUNT(*)Count all rows in each group
count(field)COUNT(field)Count non-null values of a field
countDistinct(field)COUNT(DISTINCT field)Count unique values
sum(field)SUM(field)Total of numeric values
avg(field)AVG(field)Average of numeric values
min(field)MIN(field)Smallest value
max(field)MAX(field)Largest value

Basic example

Count posts and sum views per author — a typical analytics query:

TSposts per author
const stats = await db.post.query()
.with({ author: true })
.select(({ post, author }) => ({
authorEmail: author.email,
postCount: count(),
totalViews: sum(post.viewCount),
avgViews: avg(post.viewCount),
bestPost: max(post.viewCount),
}))
.groupBy(({ post, author }) => [post.authorId, author.email])
.execute();
 
// stats: Array<{
// authorEmail: string,
// postCount: number,
// totalViews: number,
// avgViews: number,
// bestPost: number
// }>

Simple count by category

TS
// How many posts in each status?
const statusCounts = await db.post.query()
.select(({ post }) => ({
status: post.status,
total: count(),
}))
.groupBy(({ post }) => [post.status])
.execute();
 
// [{ status: 'PUBLISHED', total: 42 }, { status: 'DRAFT', total: 15 }, ...]

Count distinct

How many unique authors have published posts?

TS
const result = await db.post.query()
.select(({ post }) => ({
uniqueAuthors: countDistinct(post.authorId),
}))
.where(({ post }) => post.published.eq(true))
.execute();

Window functions

For ranking, running totals, and row numbering — see theWindow Functions page. Window functions compute values across rows without collapsing them, unlike GROUP BY.