Как посчитать Inventory Turnover в SQL
Содержание:
Зачем Inventory Turnover
Ритейлер: 10 млн в запасах. Продаёт 12 млн в год. Turnover = 1.2 — медленно. Конкурент = 8 — оборот в 7 раз быстрее, меньше capital tied up. Inventory turnover — критичная финансовая метрика.
Формула
Inventory Turnover = COGS / Avg Inventory
Days Inventory Outstanding (DIO) = 365 / Inventory TurnoverБазовый расчёт
Данные: inventory_snapshots(snapshot_date, sku, quantity, cost_per_unit), orders для COGS.
WITH avg_inventory AS (
SELECT AVG(quantity * cost_per_unit) AS avg_inventory_value
FROM inventory_snapshots
WHERE snapshot_date >= CURRENT_DATE - INTERVAL '12 months'
),
cogs_year AS (
SELECT SUM(quantity * cogs_per_unit) AS total_cogs
FROM orders
WHERE status = 'paid'
AND created_at >= CURRENT_DATE - INTERVAL '12 months'
)
SELECT
a.avg_inventory_value,
c.total_cogs,
c.total_cogs::NUMERIC / NULLIF(a.avg_inventory_value, 0) AS inventory_turnover
FROM avg_inventory a
CROSS JOIN cogs_year c;Days Inventory Outstanding
SELECT
inventory_turnover,
365.0 / NULLIF(inventory_turnover, 0) AS days_inventory_outstanding
FROM (
SELECT 5.0 AS inventory_turnover -- example
) x;DIO 30 = 30 days of inventory on hand. Низкое = эффективно. Высокое = lots stuck.
По категориям
WITH cat_avg_inv AS (
SELECT
p.category,
AVG(s.quantity * s.cost_per_unit) AS avg_inv
FROM inventory_snapshots s
JOIN products p ON p.sku = s.sku
WHERE s.snapshot_date >= CURRENT_DATE - INTERVAL '12 months'
GROUP BY p.category
),
cat_cogs AS (
SELECT
p.category,
SUM(o.quantity * o.cogs_per_unit) AS cogs
FROM orders o
JOIN products p ON p.sku = o.sku
WHERE o.status = 'paid'
AND o.created_at >= CURRENT_DATE - INTERVAL '12 months'
GROUP BY p.category
)
SELECT
c.category,
c.cogs,
a.avg_inv,
c.cogs::NUMERIC / NULLIF(a.avg_inv, 0) AS turnover,
365.0 * a.avg_inv / NULLIF(c.cogs, 0) AS dio
FROM cat_cogs c
JOIN cat_avg_inv a USING (category)
ORDER BY turnover DESC;FMCG: turnover 10-20. Fashion: 3-6. Electronics: 5-10.
Частые ошибки
Ошибка 1. End-of-period vs average inventory. Average — more accurate (учитывает sezonalitet). EOP — snapshot.
Ошибка 2. COGS vs Revenue. Turnover формула на COGS, не revenue. Иначе включаете margin — не fair.
Ошибка 3. Slow-mover hidden. Top SKUs могут вращаться быстро, dead stock skewing average. Watch distribution.
Ошибка 4. Seasonal averaging. Average inventory за 12 месяцев vs quarter — разные числа.
Ошибка 5. Shrinkage / dead stock. Inventory которая всё equal-likely shrinkage / dead stock — может быть в snapshot но not в sellable.
Связанные темы
- Как посчитать COGS в SQL
- Как посчитать gross margin в SQL
- Как посчитать GMV в SQL
- Как посчитать AOV в SQL
FAQ
Какой Inventory Turnover ok?
FMCG: 10+. Fashion: 3-6. Big-ticket retail: 5-8.
Высокий Inventory Turnover — хорошо?
Обычно да. Но: too high — stockouts, потери продаж. Sweet spot.
Days Inventory Outstanding — сколько ok?
30-60 days — норма для big-ticket. 7-15 days — FMCG.
Slow-movers — что делать?
- Markdown / promo. 2) Bundle. 3) Discontinue. 4) Liquidate.
Inventory Turnover vs Sell-Through?
Turnover — annualized. Sell-through — % продано за конкретный период (часто season).