Надёжность поставщика в SQL: вовремя и в полном объёме
Поставщик привёз весь заказ, но часть товара пришла после обещанного срока. Отчёт по общей поставленной сумме покажет полное исполнение, хотя клиенту не хватало товара вовремя. Для оценки полезно разделить долю количества, пришедшего к сроку, и долю заявок, выполненных к сроку полностью.
Согласуйте единицу приёмки
В примере заявка содержит один товар и обещанное количество. Срок включается: поставка в день due_date считается своевременной. Для заявки с несколькими позициями сначала проверяйте каждую строку, затем считайте заявку успешной только при выполнении всех обязательных позиций. Недопоставку одного товара нельзя компенсировать избытком другого.
В отчёт включены заявки, у которых срок уже наступил на выбранную дату среза. Будущие заявки ещё не обязаны быть выполнены и не должны ухудшать показатель. Отменённые и изменённые заявки требуют отдельной согласованной политики.
Сначала соберите поставки по заявке
Приходы могут быть частичными. Суммируйте только количество, принятое не позже срока и известное на дату среза. Затем ограничьте зачётное количество объёмом заявки: лишние 20 штук одной поставки не должны повышать fill rate выше 100% или перекрывать недопоставку по другой.
Самодостаточный SQLite-запрос ниже считает fill rate как долю заказанного количества, пришедшего к сроку. Здесь все количества выражены в одной сопоставимой единице. Для разнородных товаров общий показатель количества требует осторожности: коробки и килограммы складывать нельзя.
WITH orders(id,supplier,due,qty) AS (
VALUES (1,'A','2026-11-10',100),(2,'A','2026-11-10',50),
(3,'B','2026-11-10',40),(4,'B','2026-12-01',20)
), receipts(order_id,received,qty) AS (
VALUES (1,'2026-11-09',60),(1,'2026-11-11',40),(2,'2026-11-10',50)
), accepted AS (
SELECT o.id,o.supplier,o.qty,
MIN(o.qty,COALESCE(SUM(CASE WHEN r.received<=o.due THEN r.qty ELSE 0 END),0)) AS on_time
FROM orders o LEFT JOIN receipts r ON r.order_id=o.id AND r.received<='2026-11-20'
WHERE o.due<='2026-11-20'
GROUP BY o.id,o.supplier,o.qty
)
SELECT supplier,SUM(qty) AS requested,SUM(on_time) AS timely,
ROUND(1.0*SUM(on_time)/SUM(qty),6) AS fill_rate,
AVG(CASE WHEN on_time=qty THEN 1.0 ELSE 0.0 END) AS otif
FROM accepted GROUP BY supplier ORDER BY supplier;
Не усредняйте доли без определения
Для поставщика A заказаны 100 и 50 единиц. По первой заявке вовремя пришло 60, ещё 40 опоздали; вторая выполнена полностью. Fill rate равен 110/150, или примерно 73,33%. OTIF по заявкам равен 1/2, или 50%.
Среднее 60% и 100% даст 80%, но приравняет заявки разного размера. Это может быть отдельной метрикой, если бизнес именно так оценивает заявки. В статье используем долю количества с общим знаменателем и отдельно бинарное исполнение каждой заявки.
Разберите причины результата
Список неуспешных заявок должен содержать обещанный объём, количество к сроку и поздние приходы. Тогда закупщик отличит недопоставку от задержки и сможет обсудить конкретный случай с поставщиком. Один агрегированный процент не объясняет, что исправлять.
Проверьте отсутствие поставок: LEFT JOIN сохраняет заявку с нулевым исполнением. Проверьте приход ровно в срок, несколько частичных приходов и перепоставку. Для заявок с разными датами изменение обещанного срока должно иметь историю, иначе показатель можно улучшить переносом даты после факта.
Отдельно контролируйте возвраты и отмены приходных документов. Пример предполагает положительные принятые количества. В рабочем журнале сначала получите актуальный зачётный объём по правилам учёта, затем применяйте метрики.
Для регулярного отчёта сохраняйте дату среза и правило зрелости заявок. Поздний приход может увеличить итоговое исполнение за всё время, но не должен задним числом становиться своевременным. Так закупки получают два понятных сигнала: сколько не хватило к сроку и как часто поставщик выполнял обещание целиком.
От запроса к рабочей витрине
В курсе вы поработаете с предварительной агрегацией, сложными JOIN и финансовыми сверками. Автоматические тесты проверяют пропуски и дубли, а итогом становится аналитическая витрина. Эти приёмы позволяют сохранить заявки без приходов и построить метрику с проверяемым знаменателем.
Откройте программу платного курса «Продвинутый SQL: сложные запросы и задачи для собеседований».
Продолжить разбор: Как сверить два SQL-отчёта: одинаковые суммы могут скрывать ошибки.
Продолжить на практике
- Продвинутый SQL: сложные запросы и задачи для собеседований ↗
Продолжение базового SQL: сложные JOIN, оконные рамки, временные ряды, retention, воронки и рекурсивные CTE. Разбирайте примеры и пишите запросы с автоматической проверкой — от отдельных расчётов до витрины интернет-магазина.
