postgres-aggregation
Skill1 starsChanged 2 months agoMITView on GitHub
Write and review Postgres aggregation queries — GROUP BY, window functions, CTEs and the materialization gotcha, FILTER, ROLLUP/GROUPING SETS, lateral joins, keyset pagination, and materialized views for expensive rollups. Use when building a report / dashboard query, aggregating events, or when an aggregation is slow or wrong.
In this repository73 other files it gives its agents.
- AGENTS.mdAGENTS.md
- bigquery-analyticsSkill
- cache-invalidationSkill
- mongo-aggregationSkill
- mongo-modelingSkill
- postgres-indexingSkill
- redis-coordinationSkill
- redis-patternsSkill
- review-querySkill
- code-migrationSkill
- cut-releaseSkill
- data-migrationSkill
- deploy-serviceSkill
- hotfixSkill
- rollbackSkill
- design-endpointSkill
- design-eventSkill
- design-schemaSkill
- evolve-contractSkill
- scaffold-nestjs-moduleSkill
- scaffold-projectSkill
- incident-responseSkill
- investigate-bugSkill
- on-callSkill
- postmortemSkill
- audit-skillsSkill
- distill-review-styleSkill
- write-skillSkill
- debug-with-tracesSkill
- define-alertsSkill
- instrument-serviceSkill
- evaluate-dependencySkill
- grillSkill
- handoffSkill
- orientSkill
- phased-deliverySkill
- spikeSkill
- to-questionnaireSkill
- write-adrSkill
- write-prdSkill
- devops-pr-reviewSkill
- go-backend-pr-reviewSkill
- nestjs-backend-pr-reviewSkill
- python-backend-pr-reviewSkill
- react-frontend-pr-reviewSkill
- bisectSkill
- break-couplingSkill
- dead-code-sweepSkill
- deslopifySkill
- extract-moduleSkill
- rebase-cleanSkill
- resolve-merge-conflictsSkill
- split-commitSkill
- tddSkill
- wait-whatSkill
- wide-renameSkill
- bullmqSkill
- kafkaSkill
- sqs-consumerSkill
- audit-dependenciesSkill
- The first 60 shown.
The file
We split this skill into the rules it gives an agent
3 rules. About 0 are common, 0 are distinctive, and 3 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈0
Distinctive · estimate
This author's own choices. Worth a look.
3
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 26
Before PG12, WITH was always an optimization fence (materialized).
- Very specific: line 30
Use WITH x AS MATERIALIZED (…) to force it (compute once, reuse).
- Very specific: line 31
Use WITH x AS NOT MATERIALIZED (…) to force inlining (let the planner push predicates in).
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Postgres aggregation
Building blocks
GROUP BY— every non-aggregated select column must be grouped or functionally dependent on the PK. Index the group key.FILTER (WHERE …)— conditional aggregates without aCASE:count(*) FILTER (WHERE status = 'paid'). Cleaner and faster thansum(case when …).- Window functions —
row_number() / rank() / lag() / sum() OVER (PARTITION BY … ORDER BY …)when you need per-row context (running totals, "first per group", deltas) without collapsing rows. DISTINCT ON (key) … ORDER BY key, ts DESC— the latest row per key, one pass, Postgres-specific.ROLLUP/GROUPING SETS— subtotals and grand totals in one query.LATERALjoin — a subquery that references the outer row (top-N per group).generate_series— fill gaps in a time series so missing buckets show as 0.
CTEs — the materialization gotcha
Before PG12, WITH was always an optimization fence (materialized). PG12+ inlines
by default unless referenced multiple times or marked MATERIALIZED. Know your
version:
- Use
WITH x AS MATERIALIZED (…)to force it (compute once, reuse). - Use
WITH x AS NOT MATERIALIZED (…)to force inlining (let the planner push predicates in). - A deep CTE chain that's slow → check whether an unwanted fence is the cause.
Performance
EXPLAIN (ANALYZE, BUFFERS)— look for aHashAggregatespilling to disk, or aSortthat an index could serve.- Pre-aggregate hot dashboards into a materialized view; refresh on a
schedule (
REFRESH MATERIALIZED VIEW CONCURRENTLY, needs a unique index) or via a job. - For "counts by day for the last 90 days" on a huge events table → a rollup table maintained incrementally beats scanning raw events every load.
- Keyset pagination (
WHERE (ts, id) < (?, ?) ORDER BY ts DESC, id DESC LIMIT n) notOFFSET—OFFSET 100000still scans 100k rows.
Correctness
NULLis excluded by aggregates (exceptcount(*)) —avgover a column with NULLs ignores them; decide if that's right.count(DISTINCT x)is expensive; if approximate is fine, considerhll/ pre-computed.- Integer division in
sum(a)/sum(b)truncates — cast to numeric.
Anti-patterns
- ❌
OFFSETpagination on a large result set. - ❌ Re-scanning raw events for a dashboard that loads constantly (materialize).
- ❌
CASE WHENsoup whereFILTERreads clearly. - ❌ Ignoring a CTE materialization fence that's forcing a bad plan.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
Reviews can't be read right now.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

