Database: GHANA_PROD · Campaign cohort filter: loan_discount_start_date::date = '2026-03-17' · Fully paid: loan_discount_amount IS NOT NULL
Methodology notes:
Use loan_discount_start_date (not end_date) for cohort — gives 7,930 loans matching LAH exactly. ·
Prior payment recency must use LAST_REPAYMENT_DATE from LAH at PERIOD = '2026-03-17', not from loan_info_tbl (post-campaign field updated on settlement). ·
Do not join INFOBIP_SMS + MANUAL_CALLS_PRIORITY_DAILY in same query — triggers MCP false write-detection. Use date-based matching instead.
1 — Overall Summary
SELECT
COUNT(DISTINCT loan_id) AS total_loans,
COUNT(DISTINCT CASE WHEN loan_discount_amount IS NOT NULL THEN loan_id END) AS fully_paid_loans,
ROUND(100.0 * COUNT(DISTINCT CASE WHEN loan_discount_amount IS NOT NULL THEN loan_id END)
/ COUNT(DISTINCT loan_id), 1) AS conversion_pct,
ROUND(SUM(total_due_amount), 0) AS due_before_discount,
ROUND(SUM(loan_discount_min_repayment_amount), 0) AS due_after_discount,
ROUND(SUM(total_repayment_amount), 0) AS total_collected,
ROUND(100.0 * SUM(total_repayment_amount) / NULLIF(SUM(total_due_amount), 0), 1) AS yield_pct
FROM GHANA_PROD.ml.loan_info_tbl
WHERE loan_discount_start_date::date = '2026-03-17'
2 — Performance by DPD Band
SELECT
CASE
WHEN lah.DAYS_LATE < 60 THEN '30-59'
WHEN lah.DAYS_LATE < 90 THEN '60-89'
WHEN lah.DAYS_LATE < 120 THEN '90-119'
ELSE '120+'
END AS dpd_band,
COUNT(*) AS total_loans,
COUNT(CASE WHEN lit.loan_discount_amount IS NOT NULL THEN 1 END) AS fully_paid,
ROUND(100.0 * COUNT(CASE WHEN lit.loan_discount_amount IS NOT NULL THEN 1 END) / COUNT(*), 1) AS conversion_pct,
ROUND(SUM(lit.total_repayment_amount), 0) AS total_collected,
ROUND(SUM(lit.total_due_amount), 0) AS original_debt,
ROUND(100.0 * SUM(lit.total_repayment_amount) / NULLIF(SUM(lit.total_due_amount), 0), 1) AS yield_pct
FROM GHANA_PROD.ml.loan_info_tbl lit
LEFT JOIN GHANA_PROD.SEMANTIC_LAYER.LOAN_ACCOUNT_HISTORY lah
ON lit.loan_id = lah.LOAN_ID
AND lah.PERIOD = '2026-03-17'
AND lah.LOAN_DISCOUNT_START_DATE = '2026-03-17'
WHERE lit.loan_discount_start_date::date = '2026-03-17'
GROUP BY 1
ORDER BY MIN(lah.DAYS_LATE)
3 — Performance by Segment (Prior Payment Recency × DPD)
SELECT
CASE
WHEN DATEDIFF('day', lah.LAST_REPAYMENT_DATE::DATE, '2026-03-17'::DATE) IS NULL THEN 'D_never_paid'
WHEN DATEDIFF('day', lah.LAST_REPAYMENT_DATE::DATE, '2026-03-17'::DATE) <= 0 THEN 'A_campaign_day'
WHEN DATEDIFF('day', lah.LAST_REPAYMENT_DATE::DATE, '2026-03-17'::DATE) <= 7 THEN 'B_1-7d_before'
WHEN DATEDIFF('day', lah.LAST_REPAYMENT_DATE::DATE, '2026-03-17'::DATE) <= 30 THEN 'C_8-30d_before'
ELSE 'E_31d+'
END AS pmt_seg,
CASE
WHEN lah.DAYS_LATE < 60 THEN '30-59'
WHEN lah.DAYS_LATE < 90 THEN '60-89'
WHEN lah.DAYS_LATE < 120 THEN '90-119'
ELSE '120+'
END AS dpd_band,
COUNT(*) AS total_loans,
COUNT(CASE WHEN lit.loan_discount_amount IS NOT NULL THEN 1 END) AS fully_paid,
ROUND(100.0 * COUNT(CASE WHEN lit.loan_discount_amount IS NOT NULL THEN 1 END) / COUNT(*), 1) AS conversion_pct,
ROUND(SUM(lit.total_repayment_amount), 0) AS total_collected,
ROUND(SUM(lit.total_due_amount), 0) AS original_debt,
ROUND(SUM(lit.loan_discount_min_repayment_amount), 0) AS due_after_discount,
ROUND(100.0 * SUM(lit.total_repayment_amount) / NULLIF(SUM(lit.total_due_amount), 0), 1) AS yield_pct
FROM GHANA_PROD.ml.loan_info_tbl lit
LEFT JOIN GHANA_PROD.SEMANTIC_LAYER.LOAN_ACCOUNT_HISTORY lah
ON lit.loan_id = lah.LOAN_ID
AND lah.PERIOD = '2026-03-17'
AND lah.LOAN_DISCOUNT_START_DATE = '2026-03-17'
WHERE lit.loan_discount_start_date::date = '2026-03-17'
GROUP BY 1, 2
ORDER BY 1, 2
4 — Performance by LN Group
SELECT
CASE
WHEN lit.LN BETWEEN 4 AND 6 THEN 'LN_4-6'
WHEN lit.LN BETWEEN 7 AND 10 THEN 'LN_7-10'
WHEN lit.LN BETWEEN 11 AND 15 THEN 'LN_11-15'
WHEN lit.LN BETWEEN 16 AND 20 THEN 'LN_16-20'
ELSE 'LN_21+'
END AS ln_band,
COUNT(*) AS total_loans,
SUM(CASE WHEN lit.loan_discount_amount IS NOT NULL THEN 1 ELSE 0 END) AS fully_paid,
ROUND(100.0 * SUM(CASE WHEN lit.loan_discount_amount IS NOT NULL THEN 1 ELSE 0 END) / COUNT(*), 1) AS conversion_pct,
ROUND(SUM(lit.total_repayment_amount), 0) AS total_collected,
ROUND(SUM(lit.total_due_amount), 0) AS due_before_discount,
ROUND(100.0 * SUM(lit.total_repayment_amount) / NULLIF(SUM(lit.total_due_amount), 0), 1) AS yield_pct
FROM GHANA_PROD.ml.loan_info_tbl lit
WHERE lit.loan_discount_start_date::date = '2026-03-17'
GROUP BY 1
ORDER BY MIN(lit.LN)
5 — Performance by Collection Call Response
WITH base AS (
SELECT
lit.loan_id,
CASE WHEN lit.loan_discount_amount IS NOT NULL THEN 1 ELSE 0 END AS fully_paid,
lit.total_repayment_amount AS collected,
lit.total_due_amount AS due_before_discount
FROM GHANA_PROD.ml.loan_info_tbl lit
WHERE lit.loan_discount_start_date::date = '2026-03-17'
),
calls AS (
SELECT
LOAN_ID,
SUM(NUM_QUEUE_ANSWERED) AS queue_ans,
SUM(NUM_IVR_ANSWERED) AS ivr_ans,
SUM(NUM_QUEUE_ATTEMPTS) AS queue_att,
SUM(NUM_IVR_ATTEMPTS) AS ivr_att
FROM GHANA_PROD.SEMANTIC_LAYER.COLLECTION_DAILY
WHERE "Date" BETWEEN '2026-03-17' AND '2026-04-10'
GROUP BY LOAN_ID
)
SELECT
CASE
WHEN COALESCE(c.queue_ans, 0) > 0 THEN 'QUEUE_ANSWERED'
WHEN COALESCE(c.ivr_ans, 0) > 0 THEN 'IVR_ONLY'
WHEN (COALESCE(c.queue_att, 0) + COALESCE(c.ivr_att, 0)) > 0 THEN 'ATTEMPTED_NO_ANSWER'
ELSE 'NO_CONTACT'
END AS call_segment,
COUNT(*) AS total_loans,
SUM(b.fully_paid) AS fully_paid,
ROUND(100.0 * SUM(b.fully_paid) / COUNT(*), 1) AS conversion_pct,
ROUND(SUM(b.collected), 0) AS total_collected,
ROUND(100.0 * SUM(b.collected) / NULLIF(SUM(b.due_before_discount), 0), 1) AS yield_pct
FROM base b
LEFT JOIN calls c ON b.loan_id = c.LOAN_ID
GROUP BY 1
ORDER BY conversion_pct DESC
6 — SMS Batch Dates
SELECT SENT_AT::date AS sms_date, COUNT(*) AS sms_sent
FROM GHANA_PROD.DATA.INFOBIP_SMS
WHERE SENT_AT::date BETWEEN '2026-03-17' AND '2026-04-10'
AND (LOWER(TEXT) LIKE '%discount%' OR LOWER(TEXT) LIKE '%waiver%')
GROUP BY 1
ORDER BY 1
7 — SMS Attribution (Paid Within 1 Day of Any Batch)
WITH sms_dates AS (
SELECT SENT_AT::date AS sms_date
FROM GHANA_PROD.DATA.INFOBIP_SMS
WHERE SENT_AT::date BETWEEN '2026-03-17' AND '2026-04-10'
AND (LOWER(TEXT) LIKE '%discount%' OR LOWER(TEXT) LIKE '%waiver%')
GROUP BY 1
),
paid_loans AS (
SELECT loan_id, LAST_REPAYMENT_DATE::date AS repaid_dt
FROM GHANA_PROD.ml.loan_info_tbl
WHERE loan_discount_start_date::date = '2026-03-17'
AND loan_discount_amount IS NOT NULL
AND LAST_REPAYMENT_DATE IS NOT NULL
)
SELECT
COUNT(DISTINCT p.loan_id) AS paid_within_1d_any_sms,
(SELECT COUNT(*) FROM paid_loans) AS total_fully_paid
FROM paid_loans p
JOIN sms_dates s ON DATEDIFF('day', s.sms_date, p.repaid_dt) BETWEEN 0 AND 1