Как посчитать working capital в SQL
payments(user_id) и refunds(user_id). Нужно получить пользователей, у которых был платёж, но не было ни одного возврата. Какой запрос корректнее всего описывает задачу?Содержание:
Зачем working capital
Working capital — это деньги, доступные для операционных нужд. Если он отрицательный, компания не может оплатить краткосрочные обязательства и движется к неплатёжеспособности. Это главный индикатор ликвидности. SaaS-компании обычно живут с большим объёмом deferred revenue, поэтому у них working capital может быть отрицательным «здоровым» образом.
Формула
working_capital = current_assets − current_liabilitiescurrent = то, что обращается в деньги в течение 12 месяцев.
Включает:
- денежные средства и эквиваленты (cash);
- дебиторскую задолженность (AR, accounts receivable);
- запасы (inventory);
- расходы будущих периодов (prepaid expenses); −
- кредиторскую задолженность (AP, accounts payable);
- начисленные обязательства (accrued liabilities);
- текущую часть долгосрочного долга;
- доходы будущих периодов в пределах 12 месяцев (deferred revenue).
Working capital в SQL
WITH balance AS (
SELECT
SUM(CASE WHEN account_category = 'cash' THEN balance END) AS cash,
SUM(CASE WHEN account_category = 'accounts_receivable' THEN balance END) AS ar,
SUM(CASE WHEN account_category = 'inventory' THEN balance END) AS inventory,
SUM(CASE WHEN account_category = 'prepaid' THEN balance END) AS prepaid,
SUM(CASE WHEN account_category = 'accounts_payable' THEN balance END) AS ap,
SUM(CASE WHEN account_category = 'accrued_liabilities' THEN balance END) AS accrued,
SUM(CASE WHEN account_category = 'short_term_debt' THEN balance END) AS short_term_debt,
SUM(CASE WHEN account_category = 'deferred_revenue_current' THEN balance END) AS deferred_rev
FROM general_ledger
WHERE as_of_date = CURRENT_DATE
)
SELECT
COALESCE(cash, 0) + COALESCE(ar, 0) + COALESCE(inventory, 0) + COALESCE(prepaid, 0) AS current_assets,
COALESCE(ap, 0) + COALESCE(accrued, 0) + COALESCE(short_term_debt, 0) + COALESCE(deferred_rev, 0) AS current_liabilities,
(COALESCE(cash, 0) + COALESCE(ar, 0) + COALESCE(inventory, 0) + COALESCE(prepaid, 0))
- (COALESCE(ap, 0) + COALESCE(accrued, 0) + COALESCE(short_term_debt, 0) + COALESCE(deferred_rev, 0)) AS working_capital
FROM balance;Положительный — здоровая ликвидность. Отрицательный — тревожный сигнал (исключение — SaaS с deferred revenue).
Current ratio
current_ratio = current_assets / current_liabilitiesSELECT
current_assets / NULLIF(current_liabilities, 0) AS current_ratio,
CASE
WHEN current_assets / current_liabilities >= 2 THEN 'healthy'
WHEN current_assets / current_liabilities >= 1.5 THEN 'ok'
WHEN current_assets / current_liabilities >= 1 THEN 'tight'
ELSE 'critical'
END AS verdict
FROM working_capital_summary;1.5-2 — здоровый уровень. Меньше 1 — краткосрочные обязательства превышают оборотные активы.
Динамика
SELECT
DATE_TRUNC('month', as_of_date)::DATE AS month,
SUM(CASE WHEN account_category IN ('cash', 'accounts_receivable', 'inventory', 'prepaid') THEN balance ELSE 0 END) AS current_assets,
SUM(CASE WHEN account_category IN ('accounts_payable', 'accrued_liabilities', 'short_term_debt', 'deferred_revenue_current') THEN balance ELSE 0 END) AS current_liabilities,
SUM(CASE WHEN account_category IN ('cash', 'accounts_receivable', 'inventory', 'prepaid') THEN balance ELSE 0 END)
- SUM(CASE WHEN account_category IN ('accounts_payable', 'accrued_liabilities', 'short_term_debt', 'deferred_revenue_current') THEN balance ELSE 0 END) AS working_capital
FROM general_ledger
WHERE as_of_date >= CURRENT_DATE - INTERVAL '12 months'
GROUP BY DATE_TRUNC('month', as_of_date)
ORDER BY month;Частые ошибки
Ошибка 1. Включать долгосрочные обязательства. Долгосрочный долг в working capital не входит — только его текущая часть (current portion).
Ошибка 2. SaaS и deferred revenue. Годовая предоплата создаёт огромный deferred revenue. Отрицательный working capital для PLG-SaaS — это нормально: компания получила деньги вперёд.
Ошибка 3. Считать все запасы ликвидными. Залежавшиеся запасы (slow-moving inventory) могут не обратиться в деньги за 12 месяцев — их придётся продавать со скидкой или списывать.
Ошибка 4. Считать AR без резерва. Резерв по сомнительным долгам (bad debt allowance) уменьшает реально взыскиваемую дебиторскую задолженность.
Ошибка 5. Снимок вместо среднего. Снимок на конец периода считать проще, но он не отражает колебания внутри месяца. Для более точной картины берите среднее дневное значение.
Связанные темы
- Как посчитать DSO в SQL
- Как посчитать cash conversion cycle в SQL
- Как посчитать burn rate в SQL
- Как посчитать runway в SQL
FAQ
Working capital negative — плохо?
Зависит от бизнес-модели. Для SaaS с годовой предоплатой отрицательный working capital — это норма. А вот для производственной компании такой показатель — тревожный сигнал: значит, ей не хватает средств покрыть краткосрочные обязательства.
Current ratio норма?
Для большинства бизнесов здоровый current ratio — это 1.5-2. У SaaS он часто меньше 1 из-за большого deferred revenue, но в этом случае ликвидность оценивают отдельно — по запасу кэша и runway.
Quick ratio?
Quick ratio считается как (денежные средства + AR) / краткосрочные обязательства, то есть без учёта запасов. Это более строгий тест ликвидности, чем current ratio: он показывает, хватит ли самых ликвидных активов, чтобы покрыть обязательства.
Включать deferred revenue current?
Формально да — это краткосрочное обязательство. Но по смыслу deferred revenue — это уже полученные деньги, а не долг, который придётся отдавать кэшем. Поэтому многие SaaS-компании исключают его из расчёта working capital.
Дневной snapshot?
Идеально брать ежедневный срез по главной книге — он точнее всего отражает динамику. Если такой детализации нет, стандартом считается срез на конец периода.