This one took me a minute to set up correctly.
Use a window function with a ROWS BETWEEN frame to aggregate defaults and accounts over a 12-month rolling window partitioned by segment. Divide the windowed sum of defaults by the windowed sum of accounts to produce the rolling default rate, being careful to handle edge cases like insufficient history at the start of the series. Clearly alias columns and order results for readability.
Pro tip: In a banking context, mention that you would validate the query by checking that early months (with fewer than 12 prior periods) either return NULL or are explicitly flagged as partial-window estimates — regulators and risk teams care deeply about this distinction and it signals production-readiness awareness.
Confirm the table schema — month as a DATE or period key, segment as a categorical, defaults and accounts as integers — and ask whether months with no activity have explicit zero rows or are absent, since gaps affect window calculations.
Use SUM() OVER (PARTITION BY segment ORDER BY month ROWS BETWEEN 11 PRECEDING AND CURRENT ROW) to aggregate both defaults and accounts across the rolling 12-month window for each segment independently.
Divide the windowed sum of defaults by the windowed sum of accounts, using NULLIF on the denominator to avoid division-by-zero errors, and multiply by 100.0 or cast appropriately to return a percentage or decimal rate.
Add a COUNT(*) OVER the same window to detect months with fewer than 12 observations; either filter them out with a HAVING/WHERE clause or flag them with a CASE statement so consumers know the rate is based on incomplete history.
Order results by segment and month, spot-check a single segment manually by summing a 12-month slice, and consider wrapping the window logic in a CTE for clarity and reusability in downstream queries.
AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.