Как посчитать bad debt rate в SQL
Содержание:
Зачем bad debt rate
Bad debt rate — доля выручки, которую компания не получает (списания, банкротства customer, fraud chargeback). Прямой удар по прибыли. Финансовый стандарт 0.5-1.5% для B2C, 1-3% для B2B SMB, 0.1-0.5% для enterprise. Резкий рост — flag credit policy issues.
Формула
bad_debt_rate = written_off / total_revenue_billedPeriod обычно — квартал или год.
Bad debt в SQL
WITH revenue AS (
SELECT SUM(amount) AS total_billed
FROM invoices
WHERE billed_at >= '2025-01-01' AND billed_at < '2026-01-01'
),
write_offs AS (
SELECT SUM(amount) AS total_written_off
FROM bad_debt_writeoffs
WHERE writeoff_date >= '2025-01-01' AND writeoff_date < '2026-01-01'
)
SELECT
(SELECT total_billed FROM revenue) AS billed,
(SELECT total_written_off FROM write_offs) AS written_off,
(SELECT total_written_off FROM write_offs)::NUMERIC * 100
/ NULLIF((SELECT total_billed FROM revenue), 0) AS bad_debt_rate_pct;Динамика
SELECT
DATE_TRUNC('month', billed_at)::DATE AS month,
SUM(amount) AS revenue,
SUM(amount) FILTER (WHERE status = 'written_off') AS written_off,
SUM(amount) FILTER (WHERE status = 'written_off')::NUMERIC * 100
/ NULLIF(SUM(amount), 0) AS bad_debt_pct
FROM invoices
WHERE billed_at >= CURRENT_DATE - INTERVAL '12 months'
GROUP BY DATE_TRUNC('month', billed_at)
ORDER BY month;Растущий тренд = credit policy ослаб. Падающий = collections команда работает.
По сегменту customer
SELECT
customer_segment,
COUNT(DISTINCT i.invoice_id) AS invoices,
SUM(i.amount) AS revenue,
SUM(i.amount) FILTER (WHERE i.status = 'written_off') AS bad_debt,
SUM(i.amount) FILTER (WHERE i.status = 'written_off')::NUMERIC * 100
/ NULLIF(SUM(i.amount), 0) AS bad_debt_pct
FROM invoices i
JOIN customers c USING (customer_id)
WHERE i.billed_at >= CURRENT_DATE - INTERVAL '6 months'
GROUP BY customer_segment
HAVING COUNT(*) >= 100
ORDER BY bad_debt_pct DESC;SMB обычно 1-3%, Enterprise меньше 0.5%. Если SMB свыше 5% — review credit policy.
Частые ошибки
Ошибка 1. Bad debt vs delinquent. Delinquent — late payment, ещё не списан. Bad debt — списано (no expectation of recovery).
Ошибка 2. Игнорировать recovery. Часть write-offs восстанавливается через коллекторов. Net bad debt = written_off − recovered.
Ошибка 3. Не нормировать на revenue. Absolute write-off 1M$ — много или мало? Зависит от revenue.
Ошибка 4. По всему customer base. New customers (без credit history) имеют выше bad debt. Сегментируйте.
Ошибка 5. Counts vs amounts. 1 enterprise customer написать на $50k = 1 case, но материально больше 100 SMB cases по $500.
Связанные темы
- Как посчитать chargeback rate в SQL
- Как посчитать DSO в SQL
- Как посчитать gross margin в SQL
- Как посчитать payment success rate в SQL
FAQ
Какой bad debt норма?
B2C SaaS 0.5-1.5%. B2B SMB 1-3%. Enterprise меньше 0.5%.
Bad debt vs allowance for doubtful accounts?
Allowance = reserve (estimated future bad debt). Bad debt = actual write-off.
Когда списывать?
US GAAP: после 90-180 days past due. Зависит от accounting policy.
Можно ли zero bad debt?
Только если strict credit (pre-paid). Тогда теряете customers, кто бы платил.
Tracking recovery?
Yes — отдельная таблица bad_debt_recoveries. Net = gross write-off − recovery.