spec/etc/db/3.sql
2025-06-30 10:31:42 +03:00

90 lines
8.5 KiB
SQL
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
Для инсталла
- если в новой версии дата изменилась, то кажется, что прогноз нужно отнести на новую дату
- Если прежняя версия была действующей: кажется, что все действующие версии нужно оставить в прогнозе (потому что это уже факт)
а новую версию включить в прогноз с вероятностью
? Должен ли инсталл вести себя одинаково с 1-дневными ежемесами (похоже на критерий корректности модели)
Версии инсталла не интерферируют с действующими. Все действующие записываются в факт, из недействующих берется последняя
Версии ежемеса интерферируют с действующими, и для пересекающихся дат суммируются по правилу вероятностей с последней действующей
(вероятность которой автоматически принимается за 100%)
Почему тогда мы в ежемесе убираем из прогноза предыдущие действующие версии? скажем, у нас была версия на весь январь и весь март,
отмеченные как действующие
Сценарий: ежемес только март, ежемес только апрель.
Сценарий: завершение открытой услуги с dt_to
Интерференция между ежемесами - насущная необходимость. Самый важный сценарий - действующая услуга, без окончания, и новая версия с некоторой даты.
Причина криводиффа: идея закрыть действующую и запустить новую. Кажется некорректным по сравнению с формулой сложения вероятностей,
потому что на время пересечения будет просадка, которую непонятно, как компенсировать.
Как считать инсталл. Казалось бы, более простой вариант. Было состояние А. Стало состояние Б. Кажется, новая модель только частично
корректна - а именно, когда даты пересекаются, именно за счет пересечения (усреднение происходит на каждую дату). Проверить с непересекающимися диапазонами.
Например, у меня есть услуга в течение месяца, закрытая по дате, факт. Мы делаем такую же версию на следующий месяц. Что это означает?
Что мы отменили факт? (задним числом?) Мы хотим эту версию учитывать в _дополнение_ к факту? А если цепочка таких фактов?
Или учитывать все факты с вероятностью 100%?
*** Тест: поставить последней услуге флаг Действует (соглашению)
Сбивает с толку еще то, что цепочка версий и цепочка временных диапазонов кажутся параллельными,
монотонной последовательности версий как бы должна соответствовать монотонная цепочка интервалов (хотя бы для тех версий, которые учитываем)
Идея с диффами кажется ошибочной. Мы в этом случае пытаемся синтезировать сами не знаем что.
Важно: наши версии не являются коррекциями, они отражают изменения ожиданий (прогноза), а постфактум - изменение факта!
Если есть продолженный ежемес, с некоторого числа мы создаем допродажу с определенной версией. Сначала она суммируется по вероятности, потом полностью перетирает старую.
Эта версия влияет на результат только со своей dt_from (мы еще не исследовали случай, когда это dt_from зайдет в прошлое)
Для продолженного "факта" мы, очевидно, допускаем модификацию в будущем (будущее в смысле версий или в смысле дат? в смысле дат), -
допродажу, завершение
Затея: полностью повторить для инсталла поведение 1-дневных закрытых ежемесов
Прозрение (может быть): каждая сделка - это скорее изменение, чем версия. По крайней мере, мы говорим о допродаже
Кто-то скажет, какая разница. А разница - хранить дельту или результат. Вопрос, можно ли корректно и компактно сохранить дельту?
Как часто нам понадобится отменять предыдущее значение?
Если для создания дельты нам нужно больше 1 записи
- сразу окажется, что 1 результата можно достичь разными путями (неоднозначность дельты)
*/
select
--install
dayscale.dt::date
,(siv.price*siv.quantity*COALESCE(a.probability_perc,0)/100) as inst1
,(siv0.price*siv0.quantity*(100-COALESCE(a.probability_perc,0))/100) as inst0
,(select max(iiv.agreement_version) from specification_item_version iiv
join specification_item ii on (iiv.specification_item_uid=ii.specification_item_uid)
join specification isp on (ii.specification_id=isp.specification_id)
join agreement ia on (isp.contract_id=ia.contract_id AND iiv.agreement_version=ia.agreement_version)
where iiv.specification_item_uid=si.specification_item_uid) as max_a_v
,a.*
--,a0.*
,siv.*
from (SELECT dd::date as dt FROM generate_series(
'2023-01-01'::timestamp
,'2029-12-31'::timestamp
,'1 day'::interval) dd
) dayscale
left outer join specification_item_version siv on (dayscale.dt=siv.dt_from)
left outer join specification_item si on (siv.specification_item_uid=si.specification_item_uid AND si.pricing_model_id in (1))
left outer join specification s on (si.specification_id=s.specification_id)
left outer join agreement a on (s.contract_id=a.contract_id AND siv.agreement_version=a.agreement_version
AND a.agreement_version=
(select max(iiv.agreement_version) from specification_item_version iiv
join specification_item ii on (iiv.specification_item_uid=ii.specification_item_uid)
join specification isp on (ii.specification_id=isp.specification_id)
join agreement ia on (isp.contract_id=ia.contract_id AND iiv.agreement_version=ia.agreement_version)
where iiv.specification_item_uid=si.specification_item_uid
--AND ia.is_actual
))
join contract d on s.contract_id=d.contract_id
join contragent k on d.contragent_id=k.contragent_id
join svc on (si.svc_id=svc.svc_id)
left outer join agreement a0 on (s.contract_id=a0.contract_id AND a0.agreement_version=(
select max(iiv.agreement_version) from specification_item_version iiv
join specification_item ii on (iiv.specification_item_uid=ii.specification_item_uid)
join specification isp on (ii.specification_id=isp.specification_id)
join agreement ia on (isp.contract_id=ia.contract_id AND iiv.agreement_version=ia.agreement_version)
where iiv.specification_item_uid=si.specification_item_uid
AND ia.agreement_version < a.agreement_version
AND ia.is_actual)
)
left outer join specification_item_version siv0 on (siv0.specification_item_uid=si.specification_item_uid
AND siv0.agreement_version=a0.agreement_version AND (dayscale.dt=siv0.dt_from))
where d.contragent_id=3