looks like semi-working

This commit is contained in:
msyu
2025-08-22 17:33:59 +03:00
parent 3d2a6a3552
commit e7628f9100
12 changed files with 604 additions and 3 deletions
+92
View File
@@ -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'
+67
View File
@@ -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
View File
@@ -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
View File
@@ -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
+71
View File
@@ -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
View File
@@ -21,7 +21,8 @@ left outer join status s on (d.__status_status=s.status_id)
where siv.is_actual where siv.is_actual
); );
CREATE UNIQUE INDEX UX_mv_line_id on elma.mv_line (siv_uid); 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; drop materialized view if exists elma.mv_component cascade;
create materialized view elma.mv_component as ( create materialized view elma.mv_component as (
+7
View File
@@ -2,4 +2,11 @@
left outer join elma.additional_agreements a on (a.__id = ANY(siv.additional_agreement)) 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)) 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 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
-- --
+15
View File
@@ -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
+32
View File
@@ -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
+42
View File
@@ -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 (смутные воспоминания)
+53
View File
@@ -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 (смутные воспоминания)
+2 -2
View File
@@ -157,7 +157,7 @@ from (
join agreement ia on (isp.contract_id=ia.contract_id AND iiv.agreement_version=ia.agreement_version) 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 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 (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_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 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) 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) 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 where iiv.specification_item_uid=si.specification_item_uid
AND ia.agreement_version < siv.agreement_version AND ia.agreement_version < siv.agreement_version
AND ia.is_actual /*именно действующее соглашение, принимаемое за факт*/ AND ia.is_actual /*именно действующее (базовое) соглашение, принимаемое за факт*/
/*а почему тут дату не проверяем ВПР*/ /*а почему тут дату не проверяем ВПР*/
) )
) )