agentleFS
tejastn10tejastn10/workbench/skills/data/postgres-aggregation/SKILL.md

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.

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
  1. Very specific:

    Before PG12, WITH was always an optimization fence (materialized).

    line 26
  2. Very specific:

    Use WITH x AS MATERIALIZED (…) to force it (compute once, reuse).

    line 30
  3. Very specific:

    Use WITH x AS NOT MATERIALIZED (…) to force inlining (let the planner push predicates in).

    line 31

≈ “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.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

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 a CASE: count(*) FILTER (WHERE status = 'paid'). Cleaner and faster than sum(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.
  • LATERAL join — 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 a HashAggregate spilling to disk, or a Sort that 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) not OFFSET — OFFSET 100000 still scans 100k rows.

Correctness

  • NULL is excluded by aggregates (except count(*)) — avg over a column with NULLs ignores them; decide if that's right.
  • count(DISTINCT x) is expensive; if approximate is fine, consider hll / pre-computed.
  • Integer division in sum(a)/sum(b) truncates — cast to numeric.

Anti-patterns

  • ❌ OFFSET pagination on a large result set.
  • ❌ Re-scanning raw events for a dashboard that loads constantly (materialize).
  • ❌ CASE WHEN soup where FILTER reads clearly.
  • ❌ Ignoring a CTE materialization fence that's forcing a bad plan.

Download now (ZIP)

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.