nlqdb

Solve · Analysts and PMs

How do I calculate month-over-month growth or period-over-period change in SQL?

If you need month-over-month growth — this period's value versus the previous one, as a percentage — ask in plain English instead of hand-writing a LAG window function. nlqdb compiles the `LAG(...) OVER (ORDER BY ...)` and the growth formula, runs it in Postgres, and shows the SQL so you can verify the order and the divide-by-zero guard.

Analysts, PMs, and finance leads report this every cycle — MoM revenue growth, week-over-week signups, quarter-over-quarter churn, year-over-year change. It's the period-over-period problem, and the SQL is easy to get subtly wrong: you need `LAG(value) OVER (ORDER BY period)` to reach the previous row, then `(current - previous) / previous` for the percentage — with a `NULLIF` guard so the first period (no prior row) and any zero-baseline row don't divide by zero. It gets re-Googled every reporting cycle, and the ORDER BY plus the zero-guard are exactly where the number silently comes out wrong.

The snippet that solves it.

> month-over-month revenue growth as a percentage this year

What nlqdb does for this

  • Ask 'month-over-month revenue growth'; nlqdb compiles the `LAG(...) OVER (ORDER BY month)` window function and the growth formula, then runs it in Postgres.
  • Every answer returns the per-period rows plus the compiled SQL under a trace toggle (`SK-WEB-005`) — verify the ORDER BY and the zero-baseline guard.
  • Works no-code over a provisioned demo, or connect a Postgres you already run (BYO connect, `SK-DBCONN-001`) to compare your real periods.
  • Repeated growth reports hit the plan cache — content-addressed on `(goal-fingerprint, schema-hash)` (`GLOBAL-006`) — so the same comparison returns in single-digit ms.

Drop into any HTML page

<nlq-data goal="month-over-month revenue growth as a percentage this year"></nlq-data>

The growth-versus-last-period column you'd otherwise hand-write with a LAG window function and a careful divide-by-zero guard is one English goal here, with the SQL shown so you can check the order and the baseline.

What this replaces

What nlqdb doesn't try to do here

  • The period ordering must be one you can name — 'by month', 'by week'. Period-over-period needs an explicit, gap-free sort; if a period has no rows, LAG reaches the previous present row, not a zero — nlqdb won't invent the missing period for you.
  • nlqdb returns the growth rows with a read-only SELECT — it's not a BI tool maintaining a live MoM chart or refreshing the comparison on a schedule. That's a scheduled job's work.
  • The public `<nlq-data>` embed is read-scoped — it computes and surfaces the change over existing rows, it doesn't write. No write key belongs in client HTML; loading the data goes through the SDK or `POST /v1/run`.

Questions buyers ask

How do I calculate month-over-month growth in SQL?
Ask in plain English — 'month-over-month revenue growth as a percentage.' nlqdb compiles the window function (`LAG(value) OVER (ORDER BY month)` to reach last month, then `(current - previous) / previous`), runs it in Postgres, and returns the per-period rows plus the SQL it ran. You get the growth column without hand-writing LAG or the zero-baseline guard. The honest limit: you have to name the period order it compares along.
What's the difference between LAG and a self-join for period-over-period change?
Both reach the previous period's value, but `LAG(value) OVER (ORDER BY period)` is one pass over ordered rows — no join, no off-by-one on the period key. A self-join on `period = period - 1` breaks on gaps and calendar boundaries (December to January). nlqdb picks the window form and shows the compiled SQL so you can confirm the order it walked.
Can I compute year-over-year or week-over-week change too?
Yes — they're the same window family with a different order and offset: `LAG(value, 12) OVER (ORDER BY month)` reaches the same month last year, `LAG(value) OVER (ORDER BY week)` the prior week. Ask for 'year-over-year' or 'week-over-week' and nlqdb compiles the offset, then shows the SQL so you can confirm the period and the step. The honest limit: name the period and how far back to look.
Can I run period-over-period growth on a Postgres database I already run?
Yes — connect it with the signed-in BYO connect verb (`nlq db connect`, `SK-DBCONN-001`; see /solve/query-existing-postgres-in-natural-language) and ask for the growth report in place, no ETL into a separate store. The honest limits: BYO connect is signed-in only (not the public embed), and nlqdb returns the comparison with a read-only query — it doesn't persist a materialized growth column for you.

Where this pain shows up in public

Enduring discussion hubs where you can verify the theme without taking our word for it. We don't quote individual posts; we cite search-result and subreddit URLs that stay live as new threads land.

Try nlqdb in 30 seconds

No sign-in. The anonymous database lasts 72 hours; adopt it with one click if you keep it.

Start with a goal →

Looking at this from a different angle? Browse all solve pages or browse competitor comparisons.