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
1 lineimport { count, countDistinct, sum, avg, min, max } from 'zanith';| Function | SQL output | Use 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
19 linesconst 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
10 lines// 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
6 linesconst 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.