looks like semi-working
This commit is contained in:
@@ -0,0 +1,92 @@
|
||||
--explain analyze
|
||||
-- обсчет примерно 1 день за секунду
|
||||
-- попробовать оптимизировать base_line
|
||||
-- попробовать убрать mv
|
||||
-- pricing_model
|
||||
-- ВПР время выполнения резко увеличивается при переносе или просто добавлении agreement_is_actual AND в CTE, необъяснимо. Индекс не помогает. Добавление в общее условие where может очень сильно ускорить. Добавление в несколько мест может сильно ускорить
|
||||
-- ага. тут есть ошибка - возвращается разное количество строк. Что говорит о существенной ошибке в запросе
|
||||
|
||||
with line as (SELECT *,
|
||||
coalesce((LEAD(dt_from) OVER (PARTITION BY line_key ORDER BY dt_from, agreement_version,line_version)), (select max(dt) from elma.mv_dt)) dt_next
|
||||
FROM
|
||||
(
|
||||
SELECT *,
|
||||
MIN(dt_from) OVER (PARTITION BY line_key ORDER BY agreement_version desc,line_version desc) running_min_dt
|
||||
FROM elma.mv_line where siv_is_actual AND probability_pc > 0
|
||||
) t
|
||||
WHERE t.dt_from=t.running_min_dt),
|
||||
|
||||
base_line as (SELECT *,
|
||||
coalesce((LEAD(dt_from) OVER (PARTITION BY line_key ORDER BY dt_from, agreement_version,line_version)), (select max(dt) from elma.mv_dt)) dt_next,
|
||||
max(agreement_version) OVER (PARTITION BY line_key) max_agr_ver
|
||||
FROM
|
||||
(
|
||||
SELECT *,
|
||||
MIN(dt_from) OVER (PARTITION BY line_key ORDER BY agreement_version desc,line_version desc) running_min_dt
|
||||
FROM elma.mv_line where siv_is_actual AND deal_status_id IN ('5','6')
|
||||
) t
|
||||
WHERE t.dt_from=t.running_min_dt)
|
||||
|
||||
select dayscale.dt
|
||||
,sum (c.cost/dayscale.monthdays*w.probability_pc/100)
|
||||
,sum(
|
||||
case when (w.dt_to > dayscale.dt OR w.dt_to IS NULL) then
|
||||
c.cost*COALESCE(
|
||||
case when w.agreement_is_actual then 100 else w.probability_pc end
|
||||
,0)/100/dayscale.monthdays
|
||||
else 0
|
||||
end
|
||||
) as rec1
|
||||
,sum(
|
||||
case when (b.dt_to > dayscale.dt OR b.dt_to IS NULL) then 0 else
|
||||
cb.cost*(100-COALESCE(
|
||||
case when w.agreement_is_actual then 100 else w.probability_pc end
|
||||
,0))/100/dayscale.monthdays
|
||||
end
|
||||
) as rec0
|
||||
,sum(
|
||||
COALESCE(case when (w.dt_to > dayscale.dt OR w.dt_to IS NULL) then
|
||||
c.cost*(
|
||||
case when w.agreement_is_actual then 100 else w.probability_pc end
|
||||
)/100/dayscale.monthdays
|
||||
else 0 /*по окончании рабочей сделки она дает нулевой вклад*/
|
||||
end,0)
|
||||
+
|
||||
COALESCE(case when (b.dt_to > dayscale.dt OR b.dt_to IS NULL) then
|
||||
cb.cost/dayscale.monthdays*(100- COALESCE(
|
||||
case when w.agreement_is_actual then 100 else w.probability_pc end
|
||||
,0))/100
|
||||
else 0 /*по окончании базовой сделки она дает нулевой вклад*/
|
||||
end,0)
|
||||
)
|
||||
,max(w.dt_from),max(b.dt_from), max(w.probability_pc)
|
||||
,count(*)
|
||||
--,w.line_key, w.dt_from, w.dt_to, w.line_version, w.agreement_version, w.deal_status_id, w.contract, w.probability_pc
|
||||
from
|
||||
elma.mv_dt dayscale
|
||||
left outer join line w on (dayscale.dt >=w.dt_from AND dayscale.dt < w.dt_next)
|
||||
join elma.mv_component c on (w.siv_uid=c.siv_uid)
|
||||
|
||||
|
||||
left outer join base_line b on
|
||||
(b.agreement_is_actual AND w.line_key = b.line_key AND dayscale.dt >= b.dt_from AND dayscale.dt < b.dt_next
|
||||
AND b.agreement_version = (
|
||||
select max(agreement_version)
|
||||
from base_line i
|
||||
where i.line_key = w.line_key AND dayscale.dt >= i.dt_from AND dayscale.dt < i.dt_next
|
||||
AND (w.agreement_version > i.agreement_version OR w.agreement_version IS NULL)
|
||||
)
|
||||
)
|
||||
left outer join elma.mv_component cb on (b.siv_uid=cb.siv_uid)
|
||||
|
||||
where 1=1
|
||||
AND dayscale.dt between '2025-03-01' AND '2025-03-05'
|
||||
--AND w.line_key='0bfd4bfd-641b-444b-9571-b1ab3b00631e'
|
||||
|
||||
|
||||
group by dayscale.dt
|
||||
order by dayscale.dt
|
||||
|
||||
-- select * from elma.mv_line where line_key='0bfd4bfd-641b-444b-9571-b1ab3b00631e' AND probability_pc=100 order by agreement_version, line_version
|
||||
-- select * from elma.mv_line where dt_from between '2025-03-01' AND '2025-03-03'
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
--explain analyze
|
||||
with
|
||||
component as (
|
||||
select siv.__id as siv_uid, siv.discount, siv.cnt as quantity, siv.type as pricing_model_id
|
||||
,siv.hash as line_key, siv.user_description, siv.is_actual as siv_is_actual
|
||||
,siv.version, GREATEST(siv.date_nop,d."_plannedDueDate") as dt_from, siv.date_end as dt_to, siv.is_easy as is_simple, siv.cnt as quantity
|
||||
, a.__id as agreement_uid, a.contract_uid, a.is_actual as agreement_is_actual, a.deal_uid
|
||||
,d."_plannedDueDate", d.__name as deal
|
||||
,p.code, p.price, p.cnt as param_quantity, p.discount as param_discount, p.name as sku
|
||||
,p.price*p.cnt*(100-p.discount)/100 as cost
|
||||
from elma.deals_services siv
|
||||
join elma.additional_agreements a on (a.__id = ANY(siv.additional_agreement))
|
||||
join elma.deals d on (d.__id = ANY(siv.deal))
|
||||
join elma.service_parametrs p on (p.__id = ANY (siv.params))
|
||||
join elma.aggrements c on (a.contract_uid = c.__id)
|
||||
),
|
||||
|
||||
|
||||
dayscale as (SELECT dd::date as dt
|
||||
, DATE_PART('days', DATE_TRUNC('month', dd) + '1 MONTH'::INTERVAL - '1 DAY'::INTERVAL) monthdays
|
||||
FROM generate_series(
|
||||
'2025-01-01'::timestamp
|
||||
,'2025-12-10'::timestamp
|
||||
,'1 day'::interval) dd
|
||||
)
|
||||
|
||||
select * from
|
||||
dayscale
|
||||
LEFT OUTER JOIN
|
||||
(
|
||||
SELECT t.*,
|
||||
coalesce((LEAD(t.dt_from) OVER (PARTITION BY t.line_key ORDER BY t.dt_from, t.agreement_version,t.line_version)), (select max(dt) from elma.mv_dt)) dt_next,
|
||||
b.probability_pc, b.discount
|
||||
|
||||
FROM
|
||||
|
||||
|
||||
(
|
||||
SELECT *,
|
||||
MIN(dt_from) OVER (PARTITION BY line_key ORDER BY agreement_version desc,line_version desc) running_min_dt
|
||||
FROM elma.mv_line where siv_is_actual AND probability_pc > 0
|
||||
) t
|
||||
|
||||
LEFT OUTER JOIN
|
||||
|
||||
( select * from -- базовая лесенка
|
||||
(
|
||||
SELECT *,
|
||||
MIN(dt_from) OVER (PARTITION BY line_key ORDER BY agreement_version desc,line_version desc) running_min_dt
|
||||
FROM elma.mv_line where siv_is_actual AND probability_pc=100 AND agreement_is_actual
|
||||
) i where i.dt_from=i.running_min_dt
|
||||
) b on (b.siv_uid=(select siv_uid from
|
||||
( -- базовая лесенка
|
||||
SELECT siv_uid, dt_from, agreement_version, line_version,
|
||||
MIN(dt_from) OVER (PARTITION BY line_key ORDER BY agreement_version desc, line_version desc) running_min_dt
|
||||
FROM elma.mv_line where siv_is_actual AND probability_pc=100 AND agreement_is_actual
|
||||
) i where i.dt_from=i.running_min_dt
|
||||
AND i.dt_from < t.dt_from
|
||||
ORDER BY /*dt_from desc,*/ agreement_version desc, line_version desc
|
||||
LIMIT 1
|
||||
))
|
||||
where t.dt_from=t.running_min_dt -- это условие формирования лесенки, далко оторвано от ее селекта
|
||||
AND t.line_pricing_model_id in (2,3)
|
||||
|
||||
--AND t.line_key in ('0a61f9e4-520b-4f0a-aac0-c1d42c037e1b','0bde160d-52d0-4d55-b4e0-05f45cfd739e','08485a0c-a913-4332-bb36-e40dec27d12e','1809bb31-4d37-424b-ba2b-26b9a873af7f')
|
||||
) o
|
||||
on (dayscale.dt between o.dt_from AND o.dt_next)
|
||||
+112
@@ -0,0 +1,112 @@
|
||||
--explain analyze
|
||||
with
|
||||
|
||||
status(status, status_id, probability_pc) as (VALUES
|
||||
('Закрыта неуспешно',7,0),('Закрыта успешно',6,100),('Договор подписан',5,100),('Договор на подписании',15,90),('Договор на согласовании',12,70),
|
||||
('Тестирование',8,50),('Отправлено ТКП',10,20),('Внутреннее согласование',37,10),('Проработка решения',4,10),('Сбор потребностей',1,0)
|
||||
),
|
||||
|
||||
end_of_scale (dt) as (values ('2025-02-02'::timestamp)), -- этот изыск не дает видимого ускорения
|
||||
dayscale as (
|
||||
SELECT dd::date as dt
|
||||
, DATE_PART('days', DATE_TRUNC('month', dd) + '1 MONTH'::INTERVAL - '1 DAY'::INTERVAL) monthdays
|
||||
FROM end_of_scale, generate_series(
|
||||
'2025-01-01'::timestamp
|
||||
, end_of_scale.dt
|
||||
,'1 day'::interval) dd
|
||||
),
|
||||
line as (
|
||||
select siv.__id as siv_uid, siv.discount, siv.type as line_pricing_model_id
|
||||
,siv.hash as line_key, siv.user_description, siv.is_actual as siv_is_actual
|
||||
,siv.version::numeric as line_version
|
||||
, GREATEST(siv.date_nop,d."_plannedDueDate")::date as dt_from
|
||||
, COALESCE(siv.date_end::date, end_of_scale.dt) as dt_to
|
||||
,siv.is_easy as is_simple, siv.cnt as quantity -- maybe should mutliply
|
||||
, a.__id as agreement_uid, a.contract_uid, a.is_actual as agreement_is_actual, a.deal_uid, a.index as agreement_version
|
||||
,d."_plannedDueDate", d.__name as deal, d.__status_status as deal_status_id
|
||||
,c.__name as contract
|
||||
,s.probability_pc
|
||||
,(select sum(p.price*p.cnt*(100-p.discount)/100) from elma.service_parametrs p where(p.__id = ANY (siv.params))) as cost
|
||||
from elma.deals_services siv
|
||||
join elma.additional_agreements a on (a.__id = ANY(siv.additional_agreement))
|
||||
join elma.deals d on (d.__id = ANY(siv.deal))
|
||||
join elma.aggrements c on (a.contract_uid = c.__id)
|
||||
join status s on (d.__status_status=s.status_id)
|
||||
cross join end_of_scale
|
||||
)
|
||||
-- можно dt_to заменить на верх шкалы
|
||||
|
||||
|
||||
select dayscale.dt
|
||||
,sum (o.cost/dayscale.monthdays*o.probability_pc/100) as sum_unbounded
|
||||
,sum(
|
||||
case when (o.dt_to > dayscale.dt /*OR o.dt_to IS NULL*/) then
|
||||
o.cost*COALESCE(
|
||||
case when o.agreement_is_actual then 100 else o.probability_pc end
|
||||
,0)/100/dayscale.monthdays
|
||||
else 0
|
||||
end
|
||||
) as sum_working
|
||||
,sum(
|
||||
case when (o.dt_to_base > dayscale.dt /*OR o.dt_to_base IS NULL*/) then 0 else
|
||||
o.cost_base*(100-COALESCE(
|
||||
case when o.agreement_is_actual then 100 else o.probability_pc end
|
||||
,0))/100/dayscale.monthdays
|
||||
end
|
||||
) as sum_base
|
||||
,sum(
|
||||
COALESCE(case when (o.dt_to > dayscale.dt /*OR o.dt_to IS NULL*/) then
|
||||
o.cost*(
|
||||
case when o.agreement_is_actual then 100 else o.probability_pc end
|
||||
)/100/dayscale.monthdays
|
||||
else 0 /*по окончании рабочей сделки она дает нулевой вклад*/
|
||||
end,0)
|
||||
+
|
||||
COALESCE(case when (o.dt_to_base > dayscale.dt /*OR o.dt_to_base IS NULL*/) then
|
||||
o.cost_base/dayscale.monthdays*(100- COALESCE(
|
||||
case when o.agreement_is_actual then 100 else o.probability_pc end
|
||||
,0))/100
|
||||
else 0 /*по окончании базовой сделки она дает нулевой вклад*/
|
||||
end,0)
|
||||
) as sum_bounded
|
||||
,max(o.dt_from) as max_dt_from, max(o.dt_from_base) as max_dt_from_base, max(o.probability_pc) as max_probability_pc
|
||||
,count(*)
|
||||
from dayscale
|
||||
LEFT OUTER JOIN (
|
||||
SELECT t.*,
|
||||
coalesce((LEAD(t.dt_from) OVER (PARTITION BY t.line_key ORDER BY t.dt_from, t.agreement_version,t.line_version)), (select max(dt) from elma.mv_dt)) dt_next,
|
||||
b.discount as discount_base, b.quantity as quantity_base, b.dt_from as dt_from_base, b.dt_to as dt_to_base, b.cost as cost_base
|
||||
|
||||
FROM (
|
||||
SELECT *,
|
||||
MIN(dt_from) OVER (PARTITION BY line_key ORDER BY agreement_version desc,line_version desc) running_min_dt
|
||||
FROM line where siv_is_actual AND probability_pc > 0
|
||||
) t
|
||||
|
||||
LEFT OUTER JOIN (
|
||||
select * from -- базовая лесенка
|
||||
(
|
||||
SELECT *,
|
||||
MIN(dt_from) OVER (PARTITION BY line_key ORDER BY agreement_version desc,line_version desc) running_min_dt
|
||||
FROM line where siv_is_actual AND probability_pc=100 AND agreement_is_actual AND deal_status_id in (5,6)
|
||||
) i where i.dt_from=i.running_min_dt
|
||||
) b on (b.siv_uid=(
|
||||
select siv_uid from
|
||||
( -- базовая лесенка
|
||||
SELECT siv_uid, dt_from, agreement_version, line_version,
|
||||
MIN(dt_from) OVER (PARTITION BY line_key ORDER BY agreement_version desc, line_version desc) running_min_dt
|
||||
FROM line where siv_is_actual AND probability_pc=100 AND agreement_is_actual AND deal_status_id in (5,6)
|
||||
) i where i.dt_from=i.running_min_dt
|
||||
AND i.dt_from < t.dt_from
|
||||
ORDER BY /*dt_from desc,*/ agreement_version desc, line_version desc
|
||||
LIMIT 1
|
||||
)
|
||||
)
|
||||
where t.dt_from=t.running_min_dt -- это условие формирования лесенки, далко оторвано от ее селекта
|
||||
AND t.line_pricing_model_id in (2,3)
|
||||
|
||||
--AND t.line_key in ('0a61f9e4-520b-4f0a-aac0-c1d42c037e1b','0bde160d-52d0-4d55-b4e0-05f45cfd739e','08485a0c-a913-4332-bb36-e40dec27d12e','1809bb31-4d37-424b-ba2b-26b9a873af7f')
|
||||
) o
|
||||
on (o.dt_from <= dayscale.dt AND dayscale.dt < o.dt_next)
|
||||
group by dayscale.dt
|
||||
order by dayscale.dt
|
||||
+109
@@ -0,0 +1,109 @@
|
||||
--explain analyze
|
||||
with
|
||||
status(status, status_id, probability_pc) as (VALUES
|
||||
('Закрыта неуспешно',7,0),('Закрыта успешно',6,100),('Договор подписан',5,100),('Договор на подписании',15,90),('Договор на согласовании',12,70),
|
||||
('Тестирование',8,50),('Отправлено ТКП',10,20),('Внутреннее согласование',37,10),('Проработка решения',4,10),('Сбор потребностей',1,0)
|
||||
),
|
||||
begin_of_scale (dt) as (values ('2025-01-01'::timestamp)), -- этот изыск не дает видимого ускорения
|
||||
end_of_scale (dt) as (values ('2025-12-01'::timestamp)), -- этот изыск не дает видимого ускорения
|
||||
dayscale as (
|
||||
SELECT dd::date as dt
|
||||
, DATE_PART('days', DATE_TRUNC('month', dd) + '1 MONTH'::INTERVAL - '1 DAY'::INTERVAL) monthdays
|
||||
FROM begin_of_scale, end_of_scale, generate_series(
|
||||
begin_of_scale.dt
|
||||
,end_of_scale.dt
|
||||
,'1 day'::interval) dd
|
||||
),
|
||||
line as (
|
||||
select siv.__id as siv_uid, siv.discount, siv.type as line_pricing_model_id
|
||||
,siv.hash as line_key, siv.user_description, siv.is_actual as siv_is_actual
|
||||
,siv.version::numeric as line_version
|
||||
, GREATEST(siv.date_nop,d."_plannedDueDate")::date as dt_from
|
||||
, COALESCE(siv.date_end::date, end_of_scale.dt) as dt_to -- не дало видимого ускорения
|
||||
,siv.is_easy as is_simple, siv.cnt as quantity -- maybe should mutliply
|
||||
, a.__id as agreement_uid, a.contract_uid, a.is_actual as agreement_is_actual, a.deal_uid, a.index as agreement_version
|
||||
,d."_plannedDueDate", d.__name as deal, d.__status_status as deal_status_id
|
||||
,c.__name as contract
|
||||
,s.probability_pc
|
||||
,(select sum(p.price*p.cnt*(100-p.discount)/100) from elma.service_parametrs p where(p.__id = ANY (siv.params))) as cost
|
||||
from elma.deals_services siv
|
||||
join elma.additional_agreements a on (a.__id = ANY(siv.additional_agreement))
|
||||
join elma.deals d on (d.__id = ANY(siv.deal))
|
||||
join elma.aggrements c on (a.contract_uid = c.__id)
|
||||
join status s on (d.__status_status=s.status_id)
|
||||
cross join end_of_scale
|
||||
)
|
||||
|
||||
select dayscale.dt
|
||||
,sum (o.cost/dayscale.monthdays*o.probability_pc/100) as sum_unbounded
|
||||
,sum(
|
||||
case when (o.dt_to > dayscale.dt /*OR o.dt_to IS NULL*/) then
|
||||
o.cost*COALESCE(
|
||||
case when o.agreement_is_actual then 100 else o.probability_pc end
|
||||
,0)/100/dayscale.monthdays
|
||||
else 0
|
||||
end
|
||||
) as sum_working
|
||||
,sum(
|
||||
case when (o.dt_to_base > dayscale.dt /*OR o.dt_to_base IS NULL*/) then 0 else
|
||||
o.cost_base*(100-COALESCE(
|
||||
case when o.agreement_is_actual then 100 else o.probability_pc end
|
||||
,0))/100/dayscale.monthdays
|
||||
end
|
||||
) as sum_base
|
||||
,sum(
|
||||
COALESCE(case when (o.dt_to > dayscale.dt /*OR o.dt_to IS NULL*/) then
|
||||
o.cost*(
|
||||
case when o.agreement_is_actual then 100 else o.probability_pc end
|
||||
)/100/dayscale.monthdays
|
||||
else 0 /*по окончании рабочей сделки она дает нулевой вклад*/
|
||||
end,0)
|
||||
+
|
||||
COALESCE(case when (o.dt_to_base > dayscale.dt /*OR o.dt_to_base IS NULL*/) then
|
||||
o.cost_base/dayscale.monthdays*(100- COALESCE(
|
||||
case when o.agreement_is_actual then 100 else o.probability_pc end
|
||||
,0))/100
|
||||
else 0 /*по окончании базовой сделки она дает нулевой вклад*/
|
||||
end,0)
|
||||
) as sum_bounded
|
||||
,max(o.dt_from) as max_dt_from, max(o.dt_from_base) as max_dt_from_base, max(o.probability_pc) as max_probability_pc
|
||||
,count(*)
|
||||
from dayscale
|
||||
LEFT OUTER JOIN (
|
||||
SELECT t.*,
|
||||
coalesce((LEAD(t.dt_from) OVER (PARTITION BY t.line_key ORDER BY t.dt_from, t.agreement_version,t.line_version)), (select max(dt) from elma.mv_dt)) dt_next,
|
||||
b.discount as discount_base, b.quantity as quantity_base, b.dt_from as dt_from_base, b.dt_to as dt_to_base, b.cost as cost_base
|
||||
|
||||
FROM (
|
||||
SELECT *,
|
||||
MIN(dt_from) OVER (PARTITION BY line_key ORDER BY agreement_version desc,line_version desc) running_min_dt
|
||||
FROM line where siv_is_actual AND probability_pc > 0
|
||||
) t
|
||||
|
||||
LEFT OUTER JOIN (
|
||||
select * from -- базовая лесенка
|
||||
(
|
||||
SELECT *,
|
||||
MIN(dt_from) OVER (PARTITION BY line_key ORDER BY agreement_version desc,line_version desc) running_min_dt
|
||||
FROM line where siv_is_actual AND probability_pc=100 AND agreement_is_actual AND deal_status_id in (5,6)
|
||||
) i where i.dt_from=i.running_min_dt
|
||||
) b on (t.line_key=b.line_key AND b.siv_uid=(
|
||||
select siv_uid from
|
||||
( -- базовая лесенка
|
||||
SELECT siv_uid, dt_from, agreement_version, line_version,
|
||||
MIN(dt_from) OVER (PARTITION BY line_key ORDER BY agreement_version desc, line_version desc) running_min_dt
|
||||
FROM line where siv_is_actual AND probability_pc=100 AND agreement_is_actual AND deal_status_id in (5,6)
|
||||
) i where i.dt_from=i.running_min_dt
|
||||
AND i.dt_from < t.dt_from
|
||||
ORDER BY /*dt_from desc,*/ agreement_version desc, line_version desc
|
||||
LIMIT 1
|
||||
)
|
||||
)
|
||||
where t.dt_from=t.running_min_dt -- это условие формирования лесенки, далко оторвано от ее селекта
|
||||
AND t.line_pricing_model_id in (2,3)
|
||||
|
||||
--AND t.line_key in ('0a61f9e4-520b-4f0a-aac0-c1d42c037e1b','0bde160d-52d0-4d55-b4e0-05f45cfd739e','08485a0c-a913-4332-bb36-e40dec27d12e','1809bb31-4d37-424b-ba2b-26b9a873af7f')
|
||||
) o
|
||||
on (o.dt_from <= dayscale.dt AND dayscale.dt < o.dt_next)
|
||||
group by dayscale.dt
|
||||
order by dayscale.dt
|
||||
@@ -0,0 +1,71 @@
|
||||
--explain analyze
|
||||
with
|
||||
status(status, status_id, probability_pc) as (VALUES
|
||||
('Закрыта неуспешно',7,0),('Закрыта успешно',6,100),('Договор подписан',5,100),('Договор на подписании',15,90),('Договор на согласовании',12,70),
|
||||
('Тестирование',8,50),('Отправлено ТКП',10,20),('Внутреннее согласование',37,10),('Проработка решения',4,10),('Сбор потребностей',1,0)
|
||||
),
|
||||
begin_of_scale (dt) as (values ('2025-01-01'::timestamp)), -- этот изыск не дает видимого ускорения
|
||||
end_of_scale (dt) as (values ('2025-12-02'::timestamp)), -- этот изыск не дает видимого ускорения
|
||||
dayscale as (
|
||||
SELECT dd::date as dt
|
||||
, DATE_PART('days', DATE_TRUNC('month', dd) + '1 MONTH'::INTERVAL - '1 DAY'::INTERVAL) monthdays
|
||||
FROM begin_of_scale, end_of_scale, generate_series(
|
||||
begin_of_scale.dt
|
||||
,end_of_scale.dt
|
||||
,'1 day'::interval) dd
|
||||
),
|
||||
line as (
|
||||
select siv.__id as siv_uid, siv.discount, siv.type as line_pricing_model_id
|
||||
,siv.hash as line_key, siv.user_description, siv.is_actual as siv_is_actual
|
||||
,siv.version::numeric as line_version
|
||||
, GREATEST(siv.date_nop,d."_plannedDueDate")::date as dt_from
|
||||
, COALESCE(siv.date_end::date, end_of_scale.dt) as dt_to
|
||||
,siv.is_easy as is_simple, siv.cnt as quantity -- maybe should mutliply
|
||||
, a.__id as agreement_uid, a.contract_uid, a.is_actual as agreement_is_actual, a.deal_uid, a.index as agreement_version
|
||||
,d."_plannedDueDate", d.__name as deal, d.__status_status as deal_status_id
|
||||
,c.__name as contract
|
||||
,s.probability_pc
|
||||
,(select sum(p.price*p.cnt*(100-p.discount)/100) from elma.service_parametrs p where(p.__id = ANY (siv.params))) as cost
|
||||
from elma.deals_services siv
|
||||
join elma.additional_agreements a on (a.__id = ANY(siv.additional_agreement))
|
||||
join elma.deals d on (d.__id = ANY(siv.deal))
|
||||
join elma.aggrements c on (a.contract_uid = c.__id)
|
||||
join status s on (d.__status_status=s.status_id)
|
||||
cross join end_of_scale
|
||||
)
|
||||
|
||||
select dayscale.dt
|
||||
,sum (o.cost/dayscale.monthdays*o.probability_pc/100) as sum_unbounded
|
||||
,sum(o.cost*o.probability_pc/100) as sum_working
|
||||
,sum(o.cost_base*(100-COALESCE(o.probability_pc,0))) as sum_base
|
||||
,(
|
||||
COALESCE(sum(o.cost*o.probability_pc/100),0)
|
||||
+
|
||||
COALESCE(sum(o.cost_base*(100-COALESCE(o.probability_pc,0))),0)
|
||||
) as sum_bounded
|
||||
,max(o.dt_from) as max_dt_from, max(o.dt_from_base) as max_dt_from_base, max(o.probability_pc) as max_probability_pc
|
||||
,count(*)
|
||||
|
||||
from dayscale
|
||||
LEFT OUTER JOIN (
|
||||
SELECT t.*,
|
||||
b.discount as discount_base, b.quantity as quantity_base, b.dt_from as dt_from_base, b.dt_to as dt_to_base, b.cost as cost_base
|
||||
|
||||
FROM line t
|
||||
|
||||
LEFT OUTER JOIN line b on (t.line_key=b.line_key AND b.siv_uid=(
|
||||
select siv_uid
|
||||
FROM line where siv_is_actual AND probability_pc=100 AND agreement_is_actual AND deal_status_id in (5,6)
|
||||
AND ((t.agreement_version > b.agreement_version) OR (t.agreement_version = b.agreement_version AND t.line_version > b.line_version))
|
||||
ORDER BY agreement_version desc, line_version desc
|
||||
LIMIT 1
|
||||
)
|
||||
)
|
||||
where 1=1
|
||||
AND t.line_pricing_model_id in (1)
|
||||
|
||||
--AND t.line_key in ('0a61f9e4-520b-4f0a-aac0-c1d42c037e1b','0bde160d-52d0-4d55-b4e0-05f45cfd739e','08485a0c-a913-4332-bb36-e40dec27d12e','1809bb31-4d37-424b-ba2b-26b9a873af7f')
|
||||
) o
|
||||
on (o.dt_from = dayscale.dt)
|
||||
group by dayscale.dt
|
||||
order by dayscale.dt
|
||||
+2
-1
@@ -21,7 +21,8 @@ left outer join status s on (d.__status_status=s.status_id)
|
||||
where siv.is_actual
|
||||
);
|
||||
CREATE UNIQUE INDEX UX_mv_line_id on elma.mv_line (siv_uid);
|
||||
CREATE INDEX IX_mv_line_m on elma.mv_line (line_key,dt_from,line_version,agreement_version,siv_uid);
|
||||
CREATE INDEX IX_mv_line_m on elma.mv_line (line_key,dt_from,line_version,agreement_version,siv_uid,agreement_is_actual);
|
||||
--CREATE INDEX IX_mv_line_b on elma.mv_line (line_key,dt_from,line_version,agreement_version,agreement_is_actual,siv_uid,siv_is_actual, deal_status_id);
|
||||
|
||||
drop materialized view if exists elma.mv_component cascade;
|
||||
create materialized view elma.mv_component as (
|
||||
|
||||
@@ -2,4 +2,11 @@
|
||||
left outer join elma.additional_agreements a on (a.__id = ANY(siv.additional_agreement))
|
||||
left outer join elma.deals d on (d.__id = ANY(siv.deal))
|
||||
where d.__status_status in(5,6) group by hash having count(distinct GREATEST(siv.date_nop,d."_plannedDueDate")) > 1
|
||||
|
||||
select hash, siv.type, count(*), count(distinct siv.date_nop), count(distinct d."_plannedDueDate"), count(distinct GREATEST(siv.date_nop,d."_plannedDueDate"))
|
||||
from elma.deals_services siv
|
||||
left outer join elma.additional_agreements a on (a.__id = ANY(siv.additional_agreement))
|
||||
left outer join elma.deals d on (d.__id = ANY(siv.deal))
|
||||
where d.__status_status in(5,6) AND siv.type=2
|
||||
group by hash, siv.type having count(distinct GREATEST(siv.date_nop,d."_plannedDueDate")) > 1
|
||||
--
|
||||
@@ -0,0 +1,15 @@
|
||||
with siv (dt_from, agreement_version, line_version, agreement_is_actual, siv_is_actual, cost, prob)
|
||||
as (VALUES
|
||||
('2025-01-01'::date, 1, 1, true, true, 100, 100),
|
||||
('2025-02-01', 1, 10, false, true, 200, 10),
|
||||
('2025-02-01', 1, 12, true, true, 200, 100),
|
||||
('2025-03-01', 2, 20, true, true, 100, 100),
|
||||
('2025-03-01', 2, 21, true, true, 150, 100),
|
||||
('2025-02-15', 3, 30, true, true, 300, 100),
|
||||
('2025-04-01', 4, 40, false, true, 100, 100)
|
||||
)
|
||||
SELECT
|
||||
(LAST_VALUE (dt_from) OVER (ORDER BY dt_from, agreement_version,line_version RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)),
|
||||
--coalesce((LEAD(dt_from) OVER (ORDER BY dt_from, agreement_version,line_version)), (select max(dt) from elma.mv_dt)) dt_next,
|
||||
*
|
||||
from siv
|
||||
@@ -0,0 +1,32 @@
|
||||
with siv (dt_from, agreement_version, line_version, agreement_is_actual, siv_is_actual, cost, prob)
|
||||
as (VALUES
|
||||
('2025-01-01'::date, 1, 1, true, true, 100, 100),
|
||||
('2025-02-01', 1, 10, false, true, 200, 10),
|
||||
('2025-02-01', 1, 12, true, true, 200, 100),
|
||||
('2025-03-01', 2, 20, true, true, 100, 100),
|
||||
('2025-03-01', 2, 21, true, true, 150, 100),
|
||||
('2025-02-15', 3, 30, true, true, 300, 100),
|
||||
('2025-04-01', 4, 40, false, true, 100, 100),
|
||||
('2025-03-15', 2, 25, false, false, 1000, 50)
|
||||
)
|
||||
--SELECT
|
||||
--(LAST_VALUE (dt_from) OVER (ORDER BY dt_from, agreement_version,line_version RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)),
|
||||
--coalesce((LEAD(dt_from) OVER (ORDER BY dt_from, agreement_version,line_version)), (select max(dt) from elma.mv_dt)) dt_next,
|
||||
--* from siv
|
||||
-- выбрать рабочую лесенку и базовую лесенку, посмотреть на них
|
||||
SELECT b.agreement_version, b.line_version, t.*,
|
||||
coalesce((LEAD(t.dt_from) OVER (/*PARTITION BY line_key*/ ORDER BY t.dt_from, t.agreement_version,t.line_version)), (select max(dt) from elma.mv_dt)) dt_next
|
||||
FROM
|
||||
(
|
||||
SELECT *,
|
||||
MIN(dt_from) OVER (/*PARTITION BY line_key*/ ORDER BY agreement_version desc,line_version desc) running_min_dt
|
||||
FROM siv where siv_is_actual AND prob > 0
|
||||
) t
|
||||
left outer join
|
||||
(
|
||||
SELECT *,
|
||||
MIN(dt_from) OVER (/*PARTITION BY line_key*/ ORDER BY agreement_version desc,line_version desc) running_min_dt
|
||||
FROM siv where siv_is_actual AND prob=100 AND agreement_is_actual
|
||||
) b on (t.dt_from=b.dt_from AND b.dt_from=b.running_min_dt)
|
||||
WHERE t.dt_from=t.running_min_dt
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
with siv (id, dt_from, agreement_version, line_version, agreement_is_actual, siv_is_actual, cost, prob)
|
||||
as (VALUES
|
||||
(1,'2025-01-01'::date, 1, 1, true, true, 100, 100),
|
||||
(2,'2025-02-01', 1, 10, false, true, 200, 10),
|
||||
(3,'2025-02-01', 1, 12, true, true, 200, 100),
|
||||
(4,'2025-03-01', 2, 20, true, true, 100, 100),
|
||||
(5,'2025-03-01', 2, 21, true, true, 150, 100),
|
||||
(6,'2025-02-15', 3, 30, true, true, 300, 100),
|
||||
(7,'2025-04-01', 4, 40, false, true, 100, 100),
|
||||
(8,'2025-03-15', 2, 25, false, false, 1000, 50)
|
||||
)
|
||||
--SELECT
|
||||
--(LAST_VALUE (dt_from) OVER (ORDER BY dt_from, agreement_version,line_version RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)),
|
||||
--coalesce((LEAD(dt_from) OVER (ORDER BY dt_from, agreement_version,line_version)), (select max(dt) from elma.mv_dt)) dt_next,
|
||||
--* from siv
|
||||
-- выбрать рабочую лесенку и базовую лесенку, посмотреть на них
|
||||
SELECT t.*,
|
||||
coalesce((LEAD(t.dt_from) OVER (/*PARTITION BY line_key*/ ORDER BY t.dt_from, t.agreement_version,t.line_version)), (select max(dt) from elma.mv_dt)) dt_next,
|
||||
(select id from
|
||||
(
|
||||
SELECT *,
|
||||
MIN(dt_from) OVER (/*PARTITION BY line_key*/ ORDER BY agreement_version desc,line_version desc) running_min_dt
|
||||
FROM siv where siv_is_actual AND prob=100 AND agreement_is_actual
|
||||
) b where b.dt_from=b.running_min_dt
|
||||
AND b.dt_from <= t.dt_from
|
||||
ORDER BY dt_from desc, agreement_version desc,line_version desc
|
||||
LIMIT 1
|
||||
)
|
||||
|
||||
FROM
|
||||
(
|
||||
SELECT *,
|
||||
MIN(dt_from) OVER (/*PARTITION BY line_key*/ ORDER BY agreement_version desc,line_version desc) running_min_dt
|
||||
FROM siv where siv_is_actual AND prob > 0
|
||||
) t where t.dt_from=t.running_min_dt
|
||||
|
||||
|
||||
-- пытаюсь построить более эффективный расчет, нежели по каждой дате. По каждой дате сформулировать условия достаточно просто, но вычислений выходит очень много
|
||||
-- может попробовать повторить исходный расчет, но с оконными функциями (вместо подзапроса максимальной версии)
|
||||
-- вспомним, что проблема усложнилась, когда у нас не оказалось единой версии, а версия из 2 полей
|
||||
-- может быть, полезными окажутся какие-то ограничения, скажем, уникальность версии совместно с siv_is_actual (смутные воспоминания)
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
with siv (id, dt_from, agreement_version, line_version, agreement_is_actual, siv_is_actual, cost, prob)
|
||||
as (VALUES
|
||||
(10,'2025-01-01'::date, 1, 1, true, true, 100, 100),
|
||||
(20,'2025-02-01', 1, 10, false, true, 200, 10),
|
||||
(30,'2025-02-01', 1, 12, true, true, 200, 100),
|
||||
(35,'2025-02-01', 1, 13, true, true, 250, 100),
|
||||
(40,'2025-03-01', 2, 20, true, true, 100, 100),
|
||||
(50,'2025-03-01', 2, 21, true, true, 150, 100),
|
||||
(60,'2025-02-15', 3, 30, true, true, 300, 100),
|
||||
(70,'2025-04-01', 4, 40, false, true, 100, 100),
|
||||
(80,'2025-03-15', 2, 25, false, false, 1000, 50)
|
||||
)
|
||||
-- может ли базовая версия быть старше рабочей ВПР
|
||||
--SELECT
|
||||
--(LAST_VALUE (dt_from) OVER (ORDER BY dt_from, agreement_version,line_version RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)),
|
||||
--coalesce((LEAD(dt_from) OVER (ORDER BY dt_from, agreement_version,line_version)), (select max(dt) from elma.mv_dt)) dt_next,
|
||||
--* from siv
|
||||
-- выбрать рабочую лесенку и базовую лесенку, посмотреть на них
|
||||
SELECT t.*,
|
||||
coalesce((LEAD(t.dt_from) OVER (/*PARTITION BY line_key*/ ORDER BY t.dt_from, t.agreement_version,t.line_version)), (select max(dt) from elma.mv_dt)) dt_next,
|
||||
b.*
|
||||
|
||||
FROM
|
||||
(
|
||||
SELECT *,
|
||||
MIN(dt_from) OVER (/*PARTITION BY line_key*/ ORDER BY agreement_version desc,line_version desc) running_min_dt
|
||||
FROM siv where siv_is_actual AND prob > 0
|
||||
) t
|
||||
LEFT OUTER JOIN
|
||||
( select * from -- базовая лесенка
|
||||
(
|
||||
SELECT *,
|
||||
MIN(dt_from) OVER (/*PARTITION BY line_key*/ ORDER BY agreement_version desc,line_version desc) running_min_dt
|
||||
FROM siv where siv_is_actual AND prob=100 AND agreement_is_actual
|
||||
) i where i.dt_from=i.running_min_dt
|
||||
|
||||
) b on (b.id=(select id from
|
||||
( -- базовая лесенка
|
||||
SELECT id, dt_from, agreement_version, line_version,
|
||||
MIN(siv.dt_from) OVER (/*PARTITION BY line_key*/ ORDER BY siv.agreement_version desc,siv.line_version desc) running_min_dt
|
||||
FROM siv where siv_is_actual AND prob=100 AND agreement_is_actual
|
||||
) i where i.dt_from=i.running_min_dt
|
||||
AND i.dt_from < t.dt_from
|
||||
ORDER BY /*dt_from desc,*/ agreement_version desc, line_version desc
|
||||
LIMIT 1
|
||||
)) where t.dt_from=t.running_min_dt -- это условие формирования лесенки, очень оторвано от ее селекта
|
||||
|
||||
|
||||
-- пытаюсь построить более эффективный расчет, нежели по каждой дате. По каждой дате сформулировать условия достаточно просто, но вычислений выходит очень много
|
||||
-- может попробовать повторить исходный расчет, но с оконными функциями (вместо подзапроса максимальной версии)
|
||||
-- вспомним, что проблема усложнилась, когда у нас не оказалось единой версии, а версия из 2 полей
|
||||
-- может быть, полезными окажутся какие-то ограничения, скажем, уникальность версии совместно с siv_is_actual (смутные воспоминания)
|
||||
|
||||
@@ -157,7 +157,7 @@ from (
|
||||
join agreement ia on (isp.contract_id=ia.contract_id AND iiv.agreement_version=ia.agreement_version)
|
||||
where iiv.specification_item_uid=siv.specification_item_uid
|
||||
AND (dayscale.dt >= iiv.dt_from /*AND (iiv.dt_to > dayscale.dt OR iiv.dt_to IS NULL)*/)))
|
||||
/*AND ia.is_actual*/ /*свежее соглашение не обязано быть действующим*/
|
||||
/*AND ia.is_actual*/ /*рабочее соглашение не обязано быть действующим*/
|
||||
join specification_item si on (siv.specification_item_uid=si.specification_item_uid AND si.pricing_model_id in (2,3))
|
||||
join specification s on (si.specification_id=s.specification_id)
|
||||
join agreement a on (s.contract_id=a.contract_id AND a.agreement_version=siv.agreement_version)
|
||||
@@ -175,7 +175,7 @@ from (
|
||||
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 < siv.agreement_version
|
||||
AND ia.is_actual /*именно действующее соглашение, принимаемое за факт*/
|
||||
AND ia.is_actual /*именно действующее (базовое) соглашение, принимаемое за факт*/
|
||||
/*а почему тут дату не проверяем ВПР*/
|
||||
)
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user