90 lines
8.5 KiB
SQL
90 lines
8.5 KiB
SQL
/*
|
||
Для инсталла
|
||
- если в новой версии дата изменилась, то кажется, что прогноз нужно отнести на новую дату
|
||
- Если прежняя версия была действующей: кажется, что все действующие версии нужно оставить в прогнозе (потому что это уже факт)
|
||
а новую версию включить в прогноз с вероятностью
|
||
? Должен ли инсталл вести себя одинаково с 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 |