Consumer Lending Analyst Path · Mission 22 of 30Expert

Portfolio LTV stratification with seasoning

Multi-CTE with date arithmetic to derive seasoning, then CASE bucketing on LTV with multi-stat aggregation

The Brief

Marcus HollandChief Credit Officerconsumer-lending

ALCO portfolio review. Stratify the active mortgage book by `ltv_at_orig` band and report loan count, total balance, and average seasoning per band. Bands: `<0.60`, `0.60-0.79`, `0.80-0.89`, `>=0.90`. Active means `current_status` IN ('current','30dpd','60dpd','90dpd') AND product subcategory is Mortgage. Four columns: `ltv_band`, `loan_count`, `total_balance` (rounded 2 decimals), `avg_seasoning_months` (rounded 1 decimal). Sort by `ltv_band` ascending.

You'll practice

Multi-CTEBucketingDate math

Tables & columns available

lending_originationsfact17 columns
ColumnTypeKey
origination_idINTPK
app_idINTFK → lending_applications
account_idINTFK → retail_accounts
funded_dateTEXT
funded_amountREAL
term_monthsINT
interest_rateREAL
rate_typeTEXT
arm_reset_dateTEXT
fico_at_origINT
dti_at_origREAL
ltv_at_origREAL
property_valueREAL
lo_nameTEXT
channelTEXT
current_statusTEXT
closed_dateTEXT
lending_applicationsfact18 columns
ColumnTypeKey
app_idINTPK
customer_idINTFK → retail_customers
product_idINTFK → retail_products
application_dateTEXT
requested_amountREAL
requested_termINT
loan_purposeTEXT
action_takenINT
denial_reason_1INT
aus_recommendationTEXT
rate_spreadREAL
lien_statusINT
occupancyINT
ethnicityINT
raceINT
sexINT
age_bucketTEXT
property_tractTEXTFK → lending_geography
retail_productsdim6 columns
ColumnTypeKey
product_idINTPK
product_codeTEXT
product_nameTEXT
categoryTEXT
subcategoryTEXT
default_aprREAL

Hints (3)

Each hint you reveal reduces the XP you can earn. Try the query first.

Hint 1

First CTE filters the active mortgage book and derives seasoning per loan. Seasoning is "months since funded" — a date-difference in days from today's anchor (the briefing's reference date) to funded_date, scaled to months.

Hint 2

Outer SELECT: CASE bucket on `ltv_at_orig`. Reuse the M11/M13 prefix-label trick so the bands lex-sort in ascending order without a helper column.

Hint 3

Three aggregations in the outer SELECT — count, sum of balance, average seasoning. Cast inner expressions to NUMERIC before each ROUND, otherwise Postgres throws `function round(double precision, integer) does not exist`. That cast trips up almost every first attempt.