diff --git a/etc/db/10.sql b/etc/db/10.sql new file mode 100644 index 0000000..7046852 --- /dev/null +++ b/etc/db/10.sql @@ -0,0 +1,70 @@ + +trash + +with +dayscale as (SELECT dd::date as dt + , DATE_PART('days', DATE_TRUNC('month', dd) + '1 MONTH'::INTERVAL - '1 DAY'::INTERVAL) monthdays + FROM generate_series( + '2023-01-01'::timestamp + ,'2026-01-01'::timestamp + ,'1 day'::interval) dd +), + +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) +), + +line as ( +select siv.__id as siv_uid, siv.discount, siv.type as line_pricing_model_id, siv.params +,siv.hash as line_key, siv.user_description, siv.is_actual as siv_is_actual +,siv.version::numeric, GREATEST(siv.date_nop,d."_plannedDueDate")::date as dt_from, siv.date_end::date 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 +,d."_plannedDueDate", d.__name as deal, d.__status_status as deal_status_id +,c.__name as contract +,s.probability_pc +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) +), +component as ( +select line.siv_uid +,p.__id as component_uid +,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 line +join elma.service_parametrs p on (p.__id = ANY (line.params)) +) + +select + c.component_uid, c.siv_uid +,(w.dt_from) as dt_from, (w.dt_to) as dt_to +,(w.version) as working_ver, (b.version) as base_ver +,(w.line_key) as line_key, (c.code) as code +,(w.agreement_is_actual::int), (b.agreement_is_actual::int) +,c.price, c.param_quantity, w.probability_pc +,round((c.cost/*/dayscale.monthdays*/)::numeric,2) as cost_month +,(w.deal_status_id) as status_id, (w.contract) as contract + +from +-- свежая рабочая версия на каждую дату +line w +join component c on (w.siv_uid=c.siv_uid) +-- базовая версия +left outer join line b on (w.line_key = b.line_key AND w.dt_from = b.dt_from +AND b.version = (select max(version) from line i where i.line_key = b.line_key AND dayscale.dt = i.dt_from AND w.version>i.version)) +where +w.version = + (select max(version) from line i where i.line_key = w.line_key AND dayscale.dt = i.dt_from) +--c.agreement_uid='0198183f-6dbc-73f7-914a-ce1347aea1a6' +--c.contract_uid='0194a838-0351-7fea-b722-4289dfb4f240' +AND +w.contract='01914_1' AND b.deal_status_id IN ('5','6') /*нет уверенности, что наличие допсоглашения гарантирует валидность записи*/ +--AND maxver.contract_uid='0194a838-0351-7fea-b722-4289dfb4f240' +AND w.line_pricing_model_id in (2,3) -- на уровне компонента +--AND c.code='iaas.ngc.i31.ssd-f' +--group by dayscale.dt --, mv.version, mv.line_key +order by dayscale.dt \ No newline at end of file diff --git a/etc/db/11111.sql b/etc/db/11111.sql new file mode 100644 index 0000000..e7ab1d6 --- /dev/null +++ b/etc/db/11111.sql @@ -0,0 +1,58 @@ +/* +расчет актуальной версии непонятен +почему у меня в рабочей весии только завершенные сделки? проверить для незавершенных +почему у меня все версии имеют допник? +*/ +with +dayscale as (SELECT dd::date as dt + , DATE_PART('days', DATE_TRUNC('month', dd) + '1 MONTH'::INTERVAL - '1 DAY'::INTERVAL) monthdays + FROM generate_series( + '2024-01-01'::timestamp + ,'2026-01-01'::timestamp + ,'1 day'::interval) dd +), + +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) +), + +line as ( +select siv.__id as siv_uid, siv.discount, siv.type as line_pricing_model_id, siv.params +,siv.hash as line_key, siv.user_description, siv.is_actual as siv_is_actual +,siv.version as line_version +,a.index as agreement_version, GREATEST(siv.date_nop,d."_plannedDueDate")::date as dt_from, siv.date_end::date 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 +,d."_plannedDueDate", d.__name as deal, d.__status_status as deal_status_id +,c.__name as contract +,s.probability_pc +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)) +left outer join elma.aggrements c on (a.contract_uid = c.__id) +left outer join status s on (d.__status_status=s.status_id) +), + +component as ( +select line.siv_uid +,p.__id as component_uid +,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 line +join elma.service_parametrs p on (p.__id = ANY (line.params)) +) + +select w.* + +from line w +-- свежая рабочая версия на каждую дату +where + w.siv_uid=(select siv_uid from line i where i.line_key = w.line_key /*AND dayscale.dt >= coalesce (i.dt_from,'2021-01-01')*/ order by agreement_version desc, line_version desc limit 1) + + + +AND w.line_key='20241009T112450304' +--order by dayscale.dt + + diff --git a/etc/db/11_f.sql b/etc/db/11_f.sql new file mode 100644 index 0000000..419572a --- /dev/null +++ b/etc/db/11_f.sql @@ -0,0 +1,24 @@ +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) +), +component 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, GREATEST(siv.date_nop,d."_plannedDueDate")::date as dt_from, siv.date_end::date 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 +,d."_plannedDueDate", d.__name as deal, d.__status_status as deal_status_id +,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 +,c.__name as contract +,s.probability_pc +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) +join status s on (d.__status_status=s.status_id) +) +select * from component where siv_uid='01939b8b-de2c-73bc-b1e8-df8ed254e519'; diff --git a/etc/db/12.sql b/etc/db/12.sql new file mode 100644 index 0000000..bb90a0b --- /dev/null +++ b/etc/db/12.sql @@ -0,0 +1,68 @@ + +with +dayscale as (SELECT dd::date as dt + , DATE_PART('days', DATE_TRUNC('month', dd) + '1 MONTH'::INTERVAL - '1 DAY'::INTERVAL) monthdays + FROM generate_series( + '2023-01-01'::timestamp + ,'2026-01-01'::timestamp + ,'1 day'::interval) dd +), + +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) +), + +line as ( +select siv.__id as siv_uid, siv.discount, siv.type as line_pricing_model_id, siv.params +,siv.hash as line_key, siv.user_description, siv.is_actual as siv_is_actual +,siv.version::numeric, GREATEST(siv.date_nop,d."_plannedDueDate")::date as dt_from, siv.date_end::date 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 +,d."_plannedDueDate", d.__name as deal, d.__status_status as deal_status_id +,c.__name as contract +,s.probability_pc +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) +), + +component as ( +select line.siv_uid +,p.__id as component_uid +,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 line +join elma.service_parametrs p on (p.__id = ANY (line.params)) +) + +select + c.component_uid, c.siv_uid +,dayscale.dt, (w.dt_from) as dt_from, (w.dt_to) as dt_to +,(w.version) as working_ver, (b.version) as base_ver +,(w.line_key) as line_key, (c.code) as code +,(w.agreement_is_actual::int), (b.agreement_is_actual::int) +,c.price, c.param_quantity, w.probability_pc +,round((c.cost/*/dayscale.monthdays*/)::numeric,2) as cost_month +,(w.deal_status_id) as status_id, (w.contract) as contract + +from +-- свежая рабочая версия на каждую дату +dayscale +join line w on (dayscale.dt >= w.dt_from AND w.version = + (select max(version) from line i where i.line_key = w.line_key AND dayscale.dt >= i.dt_from) +) +join component c on (w.siv_uid=c.siv_uid) +-- базовая версия +left outer join line b on (w.line_key = b.line_key AND dayscale.dt >= b.dt_from +AND b.version = (select max(version) from line i where i.line_key = b.line_key AND dayscale.dt >= i.dt_from AND w.version>i.version)) +where --c.agreement_uid='0198183f-6dbc-73f7-914a-ce1347aea1a6' +--c.contract_uid='0194a838-0351-7fea-b722-4289dfb4f240' +w.contract='01914_1' +AND b.deal_status_id IN ('5','6') /*нет уверенности, что наличие допсоглашения гарантирует валидность записи*/ +AND w.line_pricing_model_id in (2,3) -- на уровне компонента +--AND c.code='iaas.ngc.i31.ssd-f' +--group by dayscale.dt --, mv.version, mv.line_key +order by dayscale.dt diff --git a/etc/db/13.sql b/etc/db/13.sql new file mode 100644 index 0000000..56b1159 --- /dev/null +++ b/etc/db/13.sql @@ -0,0 +1,86 @@ +--psql -U postgres -d dwh -h localhost -p 5432 -f D:/backup/dwh_part.20250730.sql --сначала очистить, но схема должна быть +/* +расчет актуальной версии непонятен +почему у меня в рабочей весии только завершенные сделки? проверить для незавершенных +почему у меня все версии имеют допник? +Если дата НОП не указана, игнорируем полностью +проблема подбора тестовых данных +например, сделка на какой-то момент в статусе 4, потом продвигается - мы должны это видеть +сделать селект, который показывает историю строки. +Должна ли история сделки быть видима в истории прогноза? но если у нас siv.is_actual, мы уже не имеем дело с историей, а смотрим текущее состояние? +*/ +with +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-01-02'::timestamp + ,'1 day'::interval) dd +), + +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) +), + +line as ( +select siv.__id as siv_uid, siv.discount, siv.type as line_pricing_model_id, siv.params +,siv.hash as line_key, siv.user_description, siv.is_actual as siv_is_actual +,siv.version as line_version +,a.index as agreement_version, GREATEST(siv.date_nop,d."_plannedDueDate")::date as dt_from, siv.date_end::date 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 +,d."_plannedDueDate", d.__name as deal, d.__status_status as deal_status_id +,c.__name as contract +,s.probability_pc +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)) +left outer join elma.aggrements c on (a.contract_uid = c.__id) +left outer join status s on (d.__status_status=s.status_id) +), + +component as ( +select line.siv_uid +,p.__id as component_uid +,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 line +join elma.service_parametrs p on (p.__id = ANY (line.params)) +) + +select dayscale.dt, w.* + --c.component_uid, c.siv_uid, +/* +dayscale.dt +, (w.dt_from) as dt_from, (w.dt_to) as dt_to +--, (b.dt_from) as dt_from, (b.dt_to) as dt_to +,w.siv_uid--,b.siv_uid +,(w.version) as working_ver--, (b.version) as base_ver +,(w.line_key) as line_key +--,(c.code) as code +,(w.agreement_is_actual::int)--, (b.agreement_is_actual::int) +--,c.price, c.param_quantity, w.probability_pc +--,round((c.cost)::numeric,2) as cost_month +,(w.deal_status_id) as status_id, (w.contract) as contract +*/ +from --line w +-- свежая рабочая версия на каждую дату +dayscale +left outer join line w on (dayscale.dt >= w.dt_from AND w.siv_uid = + (select siv_uid from line i where i.line_key = w.line_key AND dayscale.dt >= i.dt_from order by line_version desc, agreement_version desc limit 1) +) +--join component c on (w.siv_uid=c.siv_uid) +-- базовая версия +left outer join line b on (w.line_key = b.line_key AND dayscale.dt >= b.dt_from +AND b.agreement_version = (select max(agreement_version) from line i where i.line_key = w.line_key AND dayscale.dt >= i.dt_from AND (w.agreement_version>i.agreement_version OR w.agreement_version IS NULL))) +where --c.agreement_uid='0198183f-6dbc-73f7-914a-ce1347aea1a6' +--c.contract_uid='0194a838-0351-7fea-b722-4289dfb4f240' +1=1 +--AND b.deal_status_id IN ('5','6') /*нет уверенности, что наличие допсоглашения гарантирует валидность записи*/ +--AND w.line_pricing_model_id in (2,3) -- на уровне компонента +--AND c.code='iaas.ngc.i31.ssd-f' +--group by dayscale.dt --, mv.version, mv.line_key +--AND w.line_key='c3d43058-a033-4e01-8ef6-18c584335d46' +--order by dayscale.dt + diff --git a/etc/db/14.sql b/etc/db/14.sql new file mode 100644 index 0000000..2d0d08a --- /dev/null +++ b/etc/db/14.sql @@ -0,0 +1,77 @@ +--psql -U postgres -d dwh -h localhost -p 5432 -f D:/backup/dwh_part.20250730.sql --сначала очистить, но схема должна быть +/* +расчет актуальной версии непонятен +почему у меня в рабочей весии только завершенные сделки? проверить для незавершенных +почему у меня все версии имеют допник? +Если дата НОП не указана, игнорируем полностью +проблема подбора тестовых данных +например, сделка на какой-то момент в статусе 4, потом продвигается - мы должны это видеть +сделать селект, который показывает историю строки. +Должна ли история сделки быть видима в истории прогноза? но если у нас siv.is_actual, мы уже не имеем дело с историей, а смотрим текущее состояние? +*/ +with +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-01-02'::timestamp + ,'1 day'::interval) dd +), + +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) +), + +line as ( +select siv.__id as siv_uid, siv.discount, siv.type as line_pricing_model_id, siv.params +,siv.hash as line_key, siv.user_description, siv.is_actual as siv_is_actual +,siv.version as line_version +,a.index as agreement_version, GREATEST(siv.date_nop,d."_plannedDueDate")::date as dt_from, siv.date_end::date 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 +,d."_plannedDueDate", d.__name as deal, d.__status_status as deal_status_id +,c.__name as contract +,s.probability_pc +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)) +left outer join elma.aggrements c on (a.contract_uid = c.__id) +left outer join status s on (d.__status_status=s.status_id) +), + +component as ( +select line.siv_uid +,p.__id as component_uid +,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 line +join elma.service_parametrs p on (p.__id = ANY (line.params)) +) + +select dayscale.dt, siv.* + +from +-- свежая рабочая версия на каждую дату +dayscale +left outer join elma.deals_services siv on (1=1) + --(select siv_uid from line i where i.line_key = w.line_key AND dayscale.dt >= i.dt_from order by line_version desc, agreement_version desc limit 1) +left outer join elma.additional_agreements a on (a.__id = ANY(siv.additional_agreement) /*это только потому, что массив'*/ AND dayscale.dt >= GREATEST(siv.date_nop,d."_plannedDueDate")) +left outer join elma.deals d on (d.__id = ANY(siv.deal)) +left outer join elma.aggrements c on (a.contract_uid = c.__id) +left outer join status s on (d.__status_status=s.status_id) + +--join component c on (w.siv_uid=c.siv_uid) +-- базовая версия +--left outer join line b on (w.line_key = b.line_key AND dayscale.dt >= b.dt_from +--AND b.agreement_version = (select max(agreement_version) from line i where i.line_key = w.line_key AND dayscale.dt >= i.dt_from AND (w.agreement_version>i.agreement_version OR w.agreement_version IS NULL))) +where --c.agreement_uid='0198183f-6dbc-73f7-914a-ce1347aea1a6' +--c.contract_uid='0194a838-0351-7fea-b722-4289dfb4f240' +1=1 +--AND b.deal_status_id IN ('5','6') /*нет уверенности, что наличие допсоглашения гарантирует валидность записи*/ +AND siv.type in (2,3) -- на уровне компонента +--AND c.code='iaas.ngc.i31.ssd-f' +--group by dayscale.dt --, mv.version, mv.line_key +--AND siv.line_key='c3d43058-a033-4e01-8ef6-18c584335d46' +--order by dayscale.dt + diff --git a/etc/db/15.sql b/etc/db/15.sql new file mode 100644 index 0000000..7035180 --- /dev/null +++ b/etc/db/15.sql @@ -0,0 +1,87 @@ +--psql -U postgres -d dwh -h localhost -p 5432 -f D:/backup/dwh_part.20250730.sql --сначала очистить, но схема должна быть +/* +расчет актуальной версии непонятен +почему у меня в рабочей весии только завершенные сделки? проверить для незавершенных +почему у меня все версии имеют допник? +Если дата НОП не указана, игнорируем полностью +проблема подбора тестовых данных +например, сделка на какой-то момент в статусе 4, потом продвигается - мы должны это видеть +сделать селект, который показывает историю строки. +Должна ли история сделки быть видима в истории прогноза? но если у нас siv.is_actual, мы уже не имеем дело с историей, а смотрим текущее состояние? +*/ +with +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-01-02'::timestamp + ,'1 day'::interval) dd +), + +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) +), + +line as ( +select siv.__id as siv_uid, siv.discount, siv.type as line_pricing_model_id, siv.params +,siv.hash as line_key, siv.user_description, siv.is_actual as siv_is_actual +,siv.version as line_version +,a.index as agreement_version, GREATEST(siv.date_nop,d."_plannedDueDate")::date as dt_from, siv.date_end::date 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 +,d."_plannedDueDate", d.__name as deal, d.__status_status as deal_status_id +,c.__name as contract +,s.probability_pc +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)) +left outer join elma.aggrements c on (a.contract_uid = c.__id) +left outer join status s on (d.__status_status=s.status_id) +), + +component as ( +select line.siv_uid +,p.__id as component_uid +,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 line +join elma.service_parametrs p on (p.__id = ANY (line.params)) +) + +select dayscale.dt, siv.* + +from +-- свежая рабочая версия на каждую дату +dayscale +left outer join elma.deals_services siv on (1=1) + --(select siv_uid from line i where i.line_key = w.line_key AND dayscale.dt >= i.dt_from order by line_version desc, agreement_version desc limit 1) +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) AND dayscale.dt >= GREATEST(siv.date_nop,d."_plannedDueDate") + AND siv.__id=( + select i.__id + from elma.deals_services i + join elma.deals ideal on (ideal.__id = ANY(i.deal)) + join elma.additional_agreements ia on (ia.__id = ANY(i.additional_agreement)) + where i.hash = siv.hash AND dayscale.dt >= GREATEST(i.date_nop, d."_plannedDueDate") + order by i.version desc, ia.index desc limit 1 + ) +) +left outer join elma.aggrements c on (a.contract_uid = c.__id) +left outer join status s on (d.__status_status=s.status_id) +--left outer join elma.service_parametrs p on (p.__id = ANY (siv.params)) + +--join component c on (w.siv_uid=c.siv_uid) +-- базовая версия +--left outer join line b on (w.line_key = b.line_key AND dayscale.dt >= b.dt_from +--AND b.agreement_version = (select max(agreement_version) from line i where i.line_key = w.line_key AND dayscale.dt >= i.dt_from AND (w.agreement_version>i.agreement_version OR w.agreement_version IS NULL))) +where --c.agreement_uid='0198183f-6dbc-73f7-914a-ce1347aea1a6' +--c.contract_uid='0194a838-0351-7fea-b722-4289dfb4f240' +1=1 +--AND b.deal_status_id IN ('5','6') /*нет уверенности, что наличие допсоглашения гарантирует валидность записи*/ +AND siv.type in (2,3) -- на уровне компонента +--AND c.code='iaas.ngc.i31.ssd-f' +--group by dayscale.dt --, mv.version, mv.line_key +--AND siv.hash='5f74c32f-25d9-4b2c-8689-3345e5f4cfbf' +order by dayscale.dt + diff --git a/etc/db/16.sql b/etc/db/16.sql new file mode 100644 index 0000000..472d8dc --- /dev/null +++ b/etc/db/16.sql @@ -0,0 +1,27 @@ +--explain analyze +select dayscale.dt +,sum (c.cost/dayscale.monthdays), 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 (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 +) t +WHERE t.dt_from=t.running_min_dt) w on (dayscale.dt >=w.dt_from AND dayscale.dt = b.dt_from +AND b.agreement_version = (select max(agreement_version) from elma.mv_line i where i.line_key = w.line_key AND dayscale.dt >= i.dt_from AND (w.agreement_version>i.agreement_version OR w.agreement_version IS NULL))) + +where dayscale.dt between '2025-01-01' AND '2025-03-10' +--AND w.line_key='20241009T112450304' +--AND b.deal_status_id IN ('5','6') +group by dayscale.dt +order by dayscale.dt + diff --git a/etc/db/17.sql b/etc/db/17.sql new file mode 100644 index 0000000..2a364d3 --- /dev/null +++ b/etc/db/17.sql @@ -0,0 +1,28 @@ +--show work_mem; +--explain (analyze, verbose, buffers) +-- компоненты можно преагрегировать +select dayscale.dt, w.siv_uid, line_key +--,sum (c.cost/dayscale.monthdays) +--, 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 +(select * from elma.mv_line i where ) w on dayscale.dt >= w.dt_from + +elma.mv_line w on (dayscale.dt >= w.dt_from AND w.siv_uid = + (select siv_uid from elma.mv_line i + where i.line_key = w.line_key AND dayscale.dt >= i.dt_from + order by line_version desc, agreement_version desc limit 1) +) +--join elma.mv_component c on (w.siv_uid=c.siv_uid) +--left outer join elma.mv_line b on +--(w.line_key = b.line_key AND dayscale.dt >= b.dt_from +--AND b.agreement_version = (select max(agreement_version) from elma.mv_line i where i.line_key = w.line_key AND dayscale.dt >= i.dt_from AND (w.agreement_version>i.agreement_version OR w.agreement_version IS NULL))) + +where dayscale.dt between '2025-01-01' AND '2025-01-10' +--AND w.line_key='20241009T112450304' +--AND b.deal_status_id IN ('5','6') +--group by dayscale.dt +order by dayscale.dt +--limit 100 \ No newline at end of file diff --git a/etc/db/18.sql b/etc/db/18.sql new file mode 100644 index 0000000..03ad642 --- /dev/null +++ b/etc/db/18.sql @@ -0,0 +1,47 @@ +--explain analyze +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) +,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))) + + +where 1=1 +--AND dayscale.dt between '2025-01-01' AND '2025-02-10' +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 + diff --git a/etc/db/19.sql b/etc/db/19.sql new file mode 100644 index 0000000..faa338e --- /dev/null +++ b/etc/db/19.sql @@ -0,0 +1,32 @@ +--explain analyze +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, agreement_version 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 * +--contract, line_key, dt_from, agreement_version, line_version +from base_line +where +line_key ='0bfd4bfd-641b-444b-9571-b1ab3b00631e' +order by contract, line_key, agreement_version, line_version + +--select * from elma.mv_line where line_key='20240530T113112183'; -- кривизна какая то + +--select * from elma.deals_services where hash='20240530T113112183'; \ No newline at end of file diff --git a/etc/db/20.sql b/etc/db/20.sql new file mode 100644 index 0000000..b03c319 --- /dev/null +++ b/etc/db/20.sql @@ -0,0 +1,45 @@ +--ищем нетривиальные строки, где двигались даты в рамках подписанных соглашений (в базовых версиях) +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 contract, line_key, dt_from, agreement_version, line_version +from line +where line_key in (select line_key from line where deal_status_id in(5,6) group by line_key having count(distinct dt_from) > 1 ) +--AND line_key='20240530T113112183' +order by contract, line_key, agreement_version, line_version + +-- ВНИМАНИЕ! agreement_is_actual ставится только на последней версии соглашения, если поставить условием - никакой версионности не останется +--select * from elma.mv_line where line_key='14eeaaf0-c5f9-40f0-8949-944cfdb7ef13'; +--select * from elma.deals_services where hash='14eeaaf0-c5f9-40f0-8949-944cfdb7ef13'; +/* +SELECT *, + MIN(dt_from) OVER (PARTITION BY line_key, agreement_version ORDER BY agreement_version desc, line_version desc) running_min_dt + FROM elma.mv_line where siv_is_actual --AND agreement_is_actual --AND deal_status_id IN ('5','6') + and line_key='20240530T113112183' + order by agreement_version + */ +/* + select hash, count(*), 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 a.is_actual group by hash having count(distinct GREATEST(siv.date_nop,d."_plannedDueDate")) > 1 +*/ + --select * from elma. deals_services where hash='0ad3231a-93af-4eb0-81e0-fc678efb5419' \ No newline at end of file diff --git a/etc/db/5.sql b/etc/db/5.sql new file mode 100644 index 0000000..66615b1 --- /dev/null +++ b/etc/db/5.sql @@ -0,0 +1,32 @@ +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) +), +maxver as ( +select max(version) as version, count(*) as cnt, line_key, contract_uid from component group by line_key, contract_uid +), +dayscale as (SELECT dd::date as dt + , DATE_PART('days', DATE_TRUNC('month', dd) + '1 MONTH'::INTERVAL - '1 DAY'::INTERVAL) monthdays + FROM generate_series( + '2023-01-01'::timestamp + ,'2026-01-01'::timestamp + ,'1 day'::interval) dd + ) +select dayscale.dt, maxver.version, sum(c.cost), count(*) from +component c join dayscale on (dayscale.dt >= c.dt_from) +join maxver on (c.line_key=maxver.line_key AND c.version=maxver.version) +where --c.agreement_uid='0198183f-6dbc-73f7-914a-ce1347aea1a6' +c.contract_uid='0194a838-0351-7fea-b722-4289dfb4f240' +group by dayscale.dt, maxver.version +order by dayscale.dt \ No newline at end of file diff --git a/etc/db/555.sql b/etc/db/555.sql new file mode 100644 index 0000000..233d485 --- /dev/null +++ b/etc/db/555.sql @@ -0,0 +1,20 @@ +-- нам нужно получить лесенку рабочих версий (разобравшись между dt_from и версией) +-- на произвольную дату выбираем максимальную версию, для которой dt_from <= этой даты +-- допустим, мы рассчитываем актуальную версию на каждый dt_from, в остальных точках актуальность версии тянется от dt_from +select siv_uid, line_key, dt_from, dt_to, agreement_version, line_version, agreement_is_actual, siv_is_actual, deal_status_id, probability_pc +from elma.mv_line +where +siv_is_actual +AND probability_pc > 0 +AND contract IN ('01914_1')--,'02418_2','05042021/01') +--contract is not null +order by line_key, agreement_version, line_version +--select * from elma.mv_line where agreement_is_actual and NOT siv_is_actual -- 0 rows +--select * from elma.mv_line where NOT siv_is_actual -- >0 + + +select c.line_key, c.dt_from, c.agreement_version, c.line_version, c.agreement_is_actual, siv_is_actual, deal_status_id, probability_pc +from elma.mv_line c +join +order by line_key, agreement_version, line_version, dt_from + diff --git a/etc/db/6.sql b/etc/db/6.sql new file mode 100644 index 0000000..34a3a84 --- /dev/null +++ b/etc/db/6.sql @@ -0,0 +1,43 @@ +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, d.__status_status as deal_status_id +,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 +,c.__name as contract +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) +), +maxver as ( +select max(version) as version, count(*) as cnt, line_key, contract_uid from component group by line_key, contract_uid +), +dayscale as (SELECT dd::date as dt + , DATE_PART('days', DATE_TRUNC('month', dd) + '1 MONTH'::INTERVAL - '1 DAY'::INTERVAL) monthdays + FROM generate_series( + '2023-01-01'::timestamp + ,'2026-01-01'::timestamp + ,'1 day'::interval) dd +), +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) +) + +select dayscale.dt, maxver.version, maxver.line_key, max(c.code) as code, round(sum(c.cost/*/dayscale.monthdays*/)::numeric,2) as cost_month, count(*), +max(c.deal_status_id) as status_id +,max(contract), min(contract) +from +component c join dayscale on (dayscale.dt >= c.dt_from) +join maxver on (c.line_key=maxver.line_key AND c.version=maxver.version) +where --c.agreement_uid='0198183f-6dbc-73f7-914a-ce1347aea1a6' +--c.contract_uid='0194a838-0351-7fea-b722-4289dfb4f240' +c.contract='01914_1' +--AND maxver.contract_uid='0194a838-0351-7fea-b722-4289dfb4f240' +group by dayscale.dt, maxver.version, maxver.line_key +order by dayscale.dt \ No newline at end of file diff --git a/etc/db/66666.sql b/etc/db/66666.sql new file mode 100644 index 0000000..d772be7 --- /dev/null +++ b/etc/db/66666.sql @@ -0,0 +1,35 @@ +with +dayscale as (SELECT dd::date as dt + , DATE_PART('days', DATE_TRUNC('month', dd) + '1 MONTH'::INTERVAL - '1 DAY'::INTERVAL) monthdays + FROM generate_series( + '2023-01-01'::timestamp + ,'2026-01-01'::timestamp + ,'1 day'::interval) dd +), + +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) +), + +line as ( +select siv.__id as siv_uid, siv.discount, siv.type as line_pricing_model_id, siv.params +,siv.hash as line_key, siv.user_description, siv.is_actual as siv_is_actual +,siv.version::numeric +,a.index +, GREATEST(siv.date_nop,d."_plannedDueDate")::date as dt_from, siv.date_end::date 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 +,d."_plannedDueDate", d.__name as deal, d.__status_status as deal_status_id +,c.__name as contract +,s.probability_pc +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) +) +select +count(*) from line w +where w.line_key='6358c370-bc26-4d95-b707-06af1c8db415' +order by version \ No newline at end of file diff --git a/etc/db/7.sql b/etc/db/7.sql new file mode 100644 index 0000000..44d5c68 --- /dev/null +++ b/etc/db/7.sql @@ -0,0 +1,95 @@ +with + +dayscale as (SELECT dd::date as dt + , DATE_PART('days', DATE_TRUNC('month', dd) + '1 MONTH'::INTERVAL - '1 DAY'::INTERVAL) monthdays + FROM generate_series( + '2023-01-01'::timestamp + ,'2026-01-01'::timestamp + ,'1 day'::interval) dd +), + +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) +), + +component 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, GREATEST(siv.date_nop,d."_plannedDueDate")::date as dt_from, siv.date_end::date 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 +,d."_plannedDueDate", d.__name as deal, d.__status_status as deal_status_id +,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 +,c.__name as contract +,s.probability_pc +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) +join status s on (d.__status_status=s.status_id) +), + +maxver as ( + select max(version) as version, count(*) as cnt, dt_from, line_key, contract_uid, agreement_is_actual + from component + group by dt_from, line_key, contract_uid, agreement_is_actual +) + +select + dayscale.dt, max(c.dt_from) as dt_from, max(c.dt_to) as dt_to +,max(mv.version) as working_ver ,max(mb.version) as base_ver +, max(mv.line_key) as line_key, max(c.code) as code +,sum( + COALESCE(case when (c.dt_to > dayscale.dt OR c.dt_to IS NULL) then + c.cost*( + case when c.agreement_is_actual then 100 else c.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 + b.cost/dayscale.monthdays*(100- COALESCE( + case when c.agreement_is_actual then 100 else c.probability_pc end + ,0))/100 + else 0 /*по окончании базовой сделки она дает нулевой вклад*/ + end,0) +) as income_recurring +,sum( + case when (c.dt_to > dayscale.dt OR c.dt_to IS NULL) then + b.cost*COALESCE( + case when c.agreement_is_actual then 100 else c.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 + b.cost*(100-COALESCE( + case when c.agreement_is_actual then 100 else c.probability_pc end + ,0))/100/dayscale.monthdays + end +) as rec0 +,count(*) + + +,round(sum(c.cost/*/dayscale.monthdays*/)::numeric,2) as cost_month +,max(c.deal_status_id) as status_id, max(c.contract) as contract + +from +-- свежая версия на каждую дату +dayscale +join component c on (dayscale.dt >= c.dt_from) +join maxver mv on (c.line_key = mv.line_key AND c.version=mv.version AND dayscale.dt >= mv.dt_from) +-- базовая версия +left outer join maxver mb on (c.line_key = mb.line_key AND mv.version > mb.version AND dayscale.dt >= mb.dt_from AND mb.agreement_is_actual) +left outer join component b on (c.line_key = b.line_key AND mb.version = b.version AND dayscale.dt >= b.dt_from) +where --c.agreement_uid='0198183f-6dbc-73f7-914a-ce1347aea1a6' +--c.contract_uid='0194a838-0351-7fea-b722-4289dfb4f240' +c.contract='01914_1' AND c.deal_status_id IN ('5','6') /*нет уверенности, что наличие допсоглашения гарантирует валидность записи*/ +--AND maxver.contract_uid='0194a838-0351-7fea-b722-4289dfb4f240' +AND c.line_pricing_model_id in (2,3) -- на уровне компонента +group by dayscale.dt --, mv.version, mv.line_key +order by dayscale.dt \ No newline at end of file diff --git a/etc/db/8.sql b/etc/db/8.sql new file mode 100644 index 0000000..cac2a1f --- /dev/null +++ b/etc/db/8.sql @@ -0,0 +1,96 @@ +with + +dayscale as (SELECT dd::date as dt + , DATE_PART('days', DATE_TRUNC('month', dd) + '1 MONTH'::INTERVAL - '1 DAY'::INTERVAL) monthdays + FROM generate_series( + '2023-01-01'::timestamp + ,'2026-01-01'::timestamp + ,'1 day'::interval) dd +), + +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) +), + +component 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, GREATEST(siv.date_nop,d."_plannedDueDate")::date as dt_from, siv.date_end::date 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 +,d."_plannedDueDate", d.__name as deal, d.__status_status as deal_status_id +,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 +,c.__name as contract +,s.probability_pc +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) +join status s on (d.__status_status=s.status_id) +), + +maxver as ( + select max(version) as version, count(*) as cnt, dt_from, line_key, contract_uid, agreement_is_actual + from component + group by dt_from, line_key, contract_uid, agreement_is_actual +) + +select + dayscale.dt, max(c.dt_from) as dt_from, max(c.dt_to) as dt_to +,max(mv.version) as working_ver,max(mb.version) as base_ver +,max(mv.line_key) as line_key, max(c.code) as code +,max(mv.agreement_is_actual::int), max(mb.agreement_is_actual::int) +,sum( + COALESCE(case when (c.dt_to > dayscale.dt OR c.dt_to IS NULL) then + c.cost*( + case when c.agreement_is_actual then 100 else c.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 + b.cost/dayscale.monthdays*(100- COALESCE( + case when c.agreement_is_actual then 100 else c.probability_pc end + ,0))/100 + else 0 /*по окончании базовой сделки она дает нулевой вклад*/ + end,0) +) as income_recurring +,sum( + case when (c.dt_to > dayscale.dt OR c.dt_to IS NULL) then + b.cost*COALESCE( + case when c.agreement_is_actual then 100 else c.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 + b.cost*(100-COALESCE( + case when c.agreement_is_actual then 100 else c.probability_pc end + ,0))/100/dayscale.monthdays + end +) as rec0 +,count(*) + + +,round(sum(c.cost/*/dayscale.monthdays*/)::numeric,2) as cost_month +,max(c.deal_status_id) as status_id, max(c.contract) as contract + +from +-- свежая версия на каждую дату +dayscale +join component c on (dayscale.dt >= c.dt_from) +join maxver mv on (c.line_key = mv.line_key AND c.version=mv.version AND dayscale.dt >= mv.dt_from) +-- базовая версия +left outer join maxver mb on (c.line_key = mb.line_key AND mv.version > mb.version AND dayscale.dt >= mb.dt_from /*AND mb.agreement_is_actualcheck it*/) +left outer join component b on (c.line_key = b.line_key AND mb.version = b.version AND dayscale.dt >= b.dt_from) +where --c.agreement_uid='0198183f-6dbc-73f7-914a-ce1347aea1a6' +--c.contract_uid='0194a838-0351-7fea-b722-4289dfb4f240' +c.contract='01914_1' AND c.deal_status_id IN ('5','6') /*нет уверенности, что наличие допсоглашения гарантирует валидность записи*/ +--AND maxver.contract_uid='0194a838-0351-7fea-b722-4289dfb4f240' +AND c.line_pricing_model_id in (2,3) -- на уровне компонента +group by dayscale.dt --, mv.version, mv.line_key +order by dayscale.dt \ No newline at end of file diff --git a/etc/db/8_simple.sql b/etc/db/8_simple.sql new file mode 100644 index 0000000..6b41bc9 --- /dev/null +++ b/etc/db/8_simple.sql @@ -0,0 +1,93 @@ +with + +dayscale as (SELECT dd::date as dt + , DATE_PART('days', DATE_TRUNC('month', dd) + '1 MONTH'::INTERVAL - '1 DAY'::INTERVAL) monthdays + FROM generate_series( + '2023-01-01'::timestamp + ,'2026-01-01'::timestamp + ,'1 day'::interval) dd +), + +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) +), + +component 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, GREATEST(siv.date_nop,d."_plannedDueDate")::date as dt_from, siv.date_end::date 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 +,d."_plannedDueDate", d.__name as deal, d.__status_status as deal_status_id +,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 +,c.__name as contract +,s.probability_pc +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) +join status s on (d.__status_status=s.status_id) +), + +maxver as ( + select max(version) as version, count(*) as cnt, dt_from, line_key, contract_uid, agreement_is_actual + from component + group by dt_from, line_key, contract_uid, agreement_is_actual +) + +select + dayscale.dt, (c.dt_from) as dt_from, (c.dt_to) as dt_to +,(mv.version) as working_ver, (mb.version) as base_ver +,(mv.line_key) as line_key, (c.code) as code +,(mv.agreement_is_actual::int), (mb.agreement_is_actual::int) +,( + COALESCE(case when (c.dt_to > dayscale.dt OR c.dt_to IS NULL) then + c.cost*( + case when c.agreement_is_actual then 100 else c.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 + b.cost/dayscale.monthdays*(100- COALESCE( + case when c.agreement_is_actual then 100 else c.probability_pc end + ,0))/100 + else 0 /*по окончании базовой сделки она дает нулевой вклад*/ + end,0) +) as income_recurring +,( + case when (c.dt_to > dayscale.dt OR c.dt_to IS NULL) then + b.cost*COALESCE( + case when c.agreement_is_actual then 100 else c.probability_pc end + ,0)/100/dayscale.monthdays + else 0 + end +) as rec1 +,( + case when (b.dt_to > dayscale.dt OR b.dt_to IS NULL) then 0 else + b.cost*(100-COALESCE( + case when c.agreement_is_actual then 100 else c.probability_pc end + ,0))/100/dayscale.monthdays + end +) as rec0 +,round((c.cost/*/dayscale.monthdays*/)::numeric,2) as cost_month +,(c.deal_status_id) as status_id, (c.contract) as contract + +from +-- свежая версия на каждую дату +dayscale +join component c on (dayscale.dt = c.dt_from) +join maxver mv on (c.line_key = mv.line_key AND c.version=mv.version AND dayscale.dt = mv.dt_from) +-- базовая версия +left outer join maxver mb on (c.line_key = mb.line_key AND mv.version > mb.version AND dayscale.dt = mb.dt_from /*AND mb.agreement_is_actualcheck it*/) +left outer join component b on (c.line_key = b.line_key AND mb.version = b.version AND dayscale.dt = b.dt_from) +where --c.agreement_uid='0198183f-6dbc-73f7-914a-ce1347aea1a6' +--c.contract_uid='0194a838-0351-7fea-b722-4289dfb4f240' +c.contract='01914_1' AND c.deal_status_id IN ('5','6') /*нет уверенности, что наличие допсоглашения гарантирует валидность записи*/ +--AND maxver.contract_uid='0194a838-0351-7fea-b722-4289dfb4f240' +AND c.line_pricing_model_id in (2,3) -- на уровне компонента +--group by dayscale.dt --, mv.version, mv.line_key +order by dayscale.dt \ No newline at end of file diff --git a/etc/db/9_simple.sql b/etc/db/9_simple.sql new file mode 100644 index 0000000..4bc396c --- /dev/null +++ b/etc/db/9_simple.sql @@ -0,0 +1,66 @@ +with +dayscale as (SELECT dd::date as dt + , DATE_PART('days', DATE_TRUNC('month', dd) + '1 MONTH'::INTERVAL - '1 DAY'::INTERVAL) monthdays + FROM generate_series( + '2023-01-01'::timestamp + ,'2026-01-01'::timestamp + ,'1 day'::interval) dd +), + +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) +), + +line as ( +select siv.__id as siv_uid, siv.discount, siv.type as line_pricing_model_id, siv.params +,siv.hash as line_key, siv.user_description, siv.is_actual as siv_is_actual +,siv.version::numeric, GREATEST(siv.date_nop,d."_plannedDueDate")::date as dt_from, siv.date_end::date 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 +,d."_plannedDueDate", d.__name as deal, d.__status_status as deal_status_id +,c.__name as contract +,s.probability_pc +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) +), +component as ( +select line.siv_uid +,p.__id as component_uid +,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 line +join elma.service_parametrs p on (p.__id = ANY (line.params)) +) + +select + c.component_uid, c.siv_uid +,dayscale.dt, (w.dt_from) as dt_from, (w.dt_to) as dt_to +,(w.version) as working_ver, (b.version) as base_ver +,(w.line_key) as line_key, (c.code) as code +,(w.agreement_is_actual::int), (b.agreement_is_actual::int) +,c.price, c.param_quantity, w.probability_pc +,round((c.cost/*/dayscale.monthdays*/)::numeric,2) as cost_month +,(w.deal_status_id) as status_id, (w.contract) as contract + +from +-- свежая рабочая версия на каждую дату +dayscale +join line w on (dayscale.dt = w.dt_from AND w.version = + (select max(version) from line i where i.line_key = w.line_key AND dayscale.dt = i.dt_from) +) +join component c on (w.siv_uid=c.siv_uid) +-- базовая версия +left outer join line b on (w.line_key = b.line_key AND dayscale.dt = b.dt_from +AND b.version = (select max(version) from line i where i.line_key = b.line_key AND dayscale.dt = i.dt_from AND w.version>i.version)) +where --c.agreement_uid='0198183f-6dbc-73f7-914a-ce1347aea1a6' +--c.contract_uid='0194a838-0351-7fea-b722-4289dfb4f240' +w.contract='01914_1' AND b.deal_status_id IN ('5','6') /*нет уверенности, что наличие допсоглашения гарантирует валидность записи*/ +--AND maxver.contract_uid='0194a838-0351-7fea-b722-4289dfb4f240' +AND w.line_pricing_model_id in (2,3) -- на уровне компонента +--AND c.code='iaas.ngc.i31.ssd-f' +--group by dayscale.dt --, mv.version, mv.line_key +order by dayscale.dt \ No newline at end of file diff --git a/etc/db/base_queries.sql b/etc/db/base_queries.sql new file mode 100644 index 0000000..46aa5fb --- /dev/null +++ b/etc/db/base_queries.sql @@ -0,0 +1,27 @@ +select left(k.__name,50) as contragent, k.__id as contragent_uid, c.__name as contract, c.__id as contract_id +,left(a.__name,50) as additional_agreement, a.deal_uid, a.is_actual, a.last_aa +,left(d.__name,50) as deal, d.__status_status as deal_status, d."_plannedDueDate" +from elma.aggrements c +join elma.additional_agreements a on (c.__id=a.contract_uid) +join elma.companies k on (c.company_uid=k.__id) +join elma.deals d on (a.deal_uid=d.__id) +order by 1; + +select +s.hash +,case when length(s.user_description) >0 then left(s.user_description,50) else s.abstractive_service end as svc +,d."_plannedDueDate"::date, s.date_nop::date, s.date_end::date, s.cnt, s.is_easy +,p.code, p.cnt as quantity, p.price, p.discount +,left(k.__name,50) as contragent, k.__id as contragent_uid, c.__name as contract, c.__id as contract_uid +,left(a.__name,50) as additional_agreement, a.deal_uid, left(d.__name,50) as deal, d.__index as deal_number +,a.is_actual, a.last_aa, a.index as agreement_version +,d.__status_status as deal_status +,c.__name as contract +from elma.aggrements c +join elma.additional_agreements a on (c.__id=a.contract_uid) +join elma.companies k on (c.company_uid=k.__id) +join elma.deals d on (a.deal_uid=d.__id) +join elma.deals_services s on (d.__id=ANY(s.deal)) +join elma.service_parametrs p on(p.__id=ANY(s.params)) +order by 1 +limit 100; diff --git a/etc/db/base_queries2.sql b/etc/db/base_queries2.sql new file mode 100644 index 0000000..46aa5fb --- /dev/null +++ b/etc/db/base_queries2.sql @@ -0,0 +1,27 @@ +select left(k.__name,50) as contragent, k.__id as contragent_uid, c.__name as contract, c.__id as contract_id +,left(a.__name,50) as additional_agreement, a.deal_uid, a.is_actual, a.last_aa +,left(d.__name,50) as deal, d.__status_status as deal_status, d."_plannedDueDate" +from elma.aggrements c +join elma.additional_agreements a on (c.__id=a.contract_uid) +join elma.companies k on (c.company_uid=k.__id) +join elma.deals d on (a.deal_uid=d.__id) +order by 1; + +select +s.hash +,case when length(s.user_description) >0 then left(s.user_description,50) else s.abstractive_service end as svc +,d."_plannedDueDate"::date, s.date_nop::date, s.date_end::date, s.cnt, s.is_easy +,p.code, p.cnt as quantity, p.price, p.discount +,left(k.__name,50) as contragent, k.__id as contragent_uid, c.__name as contract, c.__id as contract_uid +,left(a.__name,50) as additional_agreement, a.deal_uid, left(d.__name,50) as deal, d.__index as deal_number +,a.is_actual, a.last_aa, a.index as agreement_version +,d.__status_status as deal_status +,c.__name as contract +from elma.aggrements c +join elma.additional_agreements a on (c.__id=a.contract_uid) +join elma.companies k on (c.company_uid=k.__id) +join elma.deals d on (a.deal_uid=d.__id) +join elma.deals_services s on (d.__id=ANY(s.deal)) +join elma.service_parametrs p on(p.__id=ANY(s.params)) +order by 1 +limit 100; diff --git a/etc/db/base_queries3.sql b/etc/db/base_queries3.sql new file mode 100644 index 0000000..84ce4c0 --- /dev/null +++ b/etc/db/base_queries3.sql @@ -0,0 +1,39 @@ +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, d.__status_status as deal_status_id +,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 +,c.__name as contract +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) +), +maxver as ( +select max(version) as version, count(*) as cnt, line_key, contract_uid from component group by line_key, contract_uid +), +dayscale as (SELECT dd::date as dt + , DATE_PART('days', DATE_TRUNC('month', dd) + '1 MONTH'::INTERVAL - '1 DAY'::INTERVAL) monthdays + FROM generate_series( + '2023-01-01'::timestamp + ,'2026-01-01'::timestamp + ,'1 day'::interval) dd + ) + +select dayscale.dt, maxver.version, maxver.line_key, round(sum(c.cost/dayscale.monthdays)::numeric,2) as cost, count(*), +max(c.deal_status_id) as status_id +,max(contract), min(contract) +from +component c join dayscale on (dayscale.dt >= c.dt_from) +join maxver on (c.line_key=maxver.line_key AND c.version=maxver.version) +where --c.agreement_uid='0198183f-6dbc-73f7-914a-ce1347aea1a6' +--c.contract_uid='0194a838-0351-7fea-b722-4289dfb4f240' +c.contract='01914_1' +--AND maxver.contract_uid='0194a838-0351-7fea-b722-4289dfb4f240' +group by dayscale.dt, maxver.version, maxver.line_key +order by dayscale.dt \ No newline at end of file diff --git a/etc/db/dwh.sql b/etc/db/dwh.sql new file mode 100644 index 0000000..856832f --- /dev/null +++ b/etc/db/dwh.sql @@ -0,0 +1,50 @@ +select * from elma.deals; +select * from elma.aggrements; +select * from elma.additional_agreements; +select * from elma.deals_services limit 100; +select * from elma.service_parametrs limit 100; --не имеет реляционной связи со строкой, только обратный массив. +-- О ужас, сюда запихнута ссылка на сделку. И код и цена +-- по какому признаку мы узнаем, что параметр это зеркало сервиса (или это не нужно впр) + + +select deal,count(*) from elma.deals_services +where is_actual +group by deal having count(*) >10 limit 100; + +select user_description, hash, version, is_actual, * +from elma.deals_services +where deal='{01907e04-8600-508d-874a-d0ebc5c14b44}' +order by __name, version; + +select deal,version, count(*) from elma.deals_services where is_actual group by deal, version having count(*)>10 + +select user_description, hash, version, is_actual, * +from elma.deals_services +where deal='{019685f8-4430-7a48-84c0-8968ede1fcad}' +order by deal, version; + +select deal,version, count(*) from elma.deals_services where is_actual group by deal, version having count(distinct version)>0 +Значит смотреть по допнику! +Проверить, у is_actual допник должен быть? + +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 df_from, date_end as dt_to, 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 +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) +), +maxver as ( +select max(version) as ver, count(*) as cnt /*, line_key, contract_uid*/ from component /*group by line_key, contract_uid*/ +) +select * from maxver +limit 100 offset 10000 + +--where NOT is_simple \ No newline at end of file diff --git a/etc/db/mv.sql b/etc/db/mv.sql new file mode 100644 index 0000000..244f6ca --- /dev/null +++ b/etc/db/mv.sql @@ -0,0 +1,48 @@ +drop materialized view if exists elma.mv_line cascade; +create materialized view elma.mv_line as ( +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) +) +select siv.__id as siv_uid, siv.discount, siv.type as line_pricing_model_id--, siv.params +,siv.hash as line_key, /*siv.user_description,*/ siv.is_actual as siv_is_actual +,siv.version::int as line_version +,a.index as agreement_version, GREATEST(siv.date_nop,d."_plannedDueDate")::date as dt_from, siv.date_end::date 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 +,d."_plannedDueDate", d.__name as deal, d.__status_status as deal_status_id +,c.__name as contract +,s.probability_pc +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)) +left outer join elma.aggrements c on (a.contract_uid = c.__id) +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); + +drop materialized view if exists elma.mv_component cascade; +create materialized view elma.mv_component as ( +select siv.__id as siv_uid +,p.__id as component_uid +,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.service_parametrs p on (p.__id = ANY(siv.params)) +where siv.is_actual +); +CREATE UNIQUE INDEX UX_mv_component_id on elma.mv_component (component_uid); +CREATE INDEX IX_mv_component_siv on elma.mv_component (siv_uid); +--select * from elma.mv_component; + +drop materialized view if exists elma.mv_dt cascade; +create materialized view elma.mv_dt AS +SELECT dd::date as dt + , DATE_PART('days', DATE_TRUNC('month', dd) + '1 MONTH'::INTERVAL - '1 DAY'::INTERVAL) monthdays + FROM generate_series( + '2023-01-01'::timestamp + ,'2026-01-01'::timestamp + ,'1 day'::interval) dd; +CREATE UNIQUE INDEX UX_mv_dt on elma.mv_dt(dt); \ No newline at end of file diff --git a/etc/db/non-trivial-dates.sql b/etc/db/non-trivial-dates.sql new file mode 100644 index 0000000..a377a49 --- /dev/null +++ b/etc/db/non-trivial-dates.sql @@ -0,0 +1,5 @@ + select hash, 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) group by hash having count(distinct GREATEST(siv.date_nop,d."_plannedDueDate")) > 1 + -- \ No newline at end of file diff --git a/etc/db/null_agreement.sql b/etc/db/null_agreement.sql new file mode 100644 index 0000000..a2caa79 --- /dev/null +++ b/etc/db/null_agreement.sql @@ -0,0 +1,32 @@ +with +dayscale as (SELECT dd::date as dt + , DATE_PART('days', DATE_TRUNC('month', dd) + '1 MONTH'::INTERVAL - '1 DAY'::INTERVAL) monthdays + FROM generate_series( + '2023-01-01'::timestamp + ,'2026-01-01'::timestamp + ,'1 day'::interval) dd +), + +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) +), + +line as ( +select siv.__id as siv_uid, siv.discount, siv.type as line_pricing_model_id, siv.params +,siv.hash as line_key, siv.user_description, siv.is_actual as siv_is_actual +,siv.version::numeric +,a.index +, GREATEST(siv.date_nop,d."_plannedDueDate")::date as dt_from, siv.date_end::date 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 +,d."_plannedDueDate", d.__name as deal, d.__status_status as deal_status_id +,c.__name as contract +,s.probability_pc +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)) +left outer join elma.aggrements c on (a.contract_uid = c.__id) +left outer join status s on (d.__status_status=s.status_id) +) +select * from line where deal_status_id=4 \ No newline at end of file diff --git a/etc/db/test-data-dbo.sql b/etc/db/test-data-dbo.sql new file mode 100644 index 0000000..4cff8f1 --- /dev/null +++ b/etc/db/test-data-dbo.sql @@ -0,0 +1,65 @@ +-- тестовый набор данных - искать в реальном наборе тягостно +drop table if exists siv cascade; +create table siv ( + siv_id int NOT NULL PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY, + line_key varchar(255) NOT NULL, + dt_from date NOT NULL, + agreement_version int NOT NULL, + line_version int NOT NULL, + cost int NULL, + descr text NULL +); +insert into siv (line_key,dt_from,agreement_version,line_version,cost) +values +('line-01', '2025-03-01', 1, 1, 100), +('line-01', '2025-04-01', 1, 2, 100), -- сдвиг на месяц позже +('line-01', '2025-02-01', 2, 1, 200), -- сдвиг на 2 месяца раньше и увеличение +('line-01', '2025-05-01', 3, 1, 250), -- сдвиг на 3 месяца позже и увеличение +('line-01', '2025-05-01', 3, 2, 130), -- уменьшение без сдвига +('line-01', '2025-06-01', 4, 1, 160) -- сдвиг и увеличение +; +select s.*, (select ) +from siv s + +--https://stackoverflow.com/questions/74296984/how-can-i-discard-rows-that-are-out-of-order +SELECT *, +LEAD(dt_from) OVER (PARTITION BY line_key ORDER BY dt_from) dt_next +FROM +( + SELECT *, + MIN(dt_from) OVER (PARTITION BY line_key ORDER BY agreement_version desc,line_version desc) mn + + FROM siv +) t +WHERE t.dt_from=t.mn +order by siv_id +; +-- демонстрирует коллизию совпадающих дат +-- для совпадающих дат нам просто нужно взять старшую + +SELECT *, +(select min(dt_from) from siv i where i.dt_from > t.dt_from AND i.line_key=t.line_key) dt_next +FROM +( + SELECT *, + MIN(dt_from) OVER (PARTITION BY line_key ORDER BY agreement_version desc,line_version desc) mn + FROM siv +) t +WHERE t.dt_from=t.mn -- получаем лесенку, в которой порядок дат соответствует порядку версий +order by siv_id +; + +SELECT *, +LEAD(dt_from) OVER (PARTITION BY line_key ORDER BY dt_from, agreement_version,line_version) dt_next +FROM +( + SELECT *, + MIN(dt_from) OVER (PARTITION BY line_key ORDER BY agreement_version desc,line_version desc) mn + + FROM siv +) t +WHERE t.dt_from=t.mn +order by siv_id +; +-- в данном случае siv_id=4 имеет нулевой интервал и не будет учтена в расчетах, хотя и даст лишнее чтение +-- вместо null мы можем взять верхнюю границу диапазона \ No newline at end of file diff --git a/etc/db/потуги.sql b/etc/db/потуги.sql new file mode 100644 index 0000000..8403198 --- /dev/null +++ b/etc/db/потуги.sql @@ -0,0 +1,48 @@ +select * from elma.deals; +select * from elma.aggrements; +select * from elma.additional_agreements; +select * from elma.deals_services limit 100; +select * from elma.service_parametrs limit 100; --не имеет реляционной связи со строкой, только обратный массив. +-- О ужас, сюда запихнута ссылка на сделку. И код и цена +-- по какому признаку мы узнаем, что параметр это зеркало сервиса (или это не нужно впр) + + +select deal,count(*) from elma.deals_services +where is_actual +group by deal having count(*) >10 limit 100; + +select user_description, hash, version, is_actual, * +from elma.deals_services +where deal='{01907e04-8600-508d-874a-d0ebc5c14b44}' +order by __name, version; + +select deal,version, count(*) from elma.deals_services where is_actual group by deal, version having count(*)>10 + +select user_description, hash, version, is_actual, * +from elma.deals_services +where deal='{019685f8-4430-7a48-84c0-8968ede1fcad}' +order by deal, version; + +select deal,version, count(*) from elma.deals_services where is_actual group by deal, version having count(distinct version)>0 +Значит смотреть по допнику! +Проверить, у is_actual допник должен быть? + +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, date_nop as df_from, date_end as dt_to, 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 +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)) +) +select * from component +where NOT is_simple +limit 100 offset 10000 + +--where + diff --git a/etc/spec.txt b/etc/spec.txt index c3484d9..f9d773f 100644 --- a/etc/spec.txt +++ b/etc/spec.txt @@ -1,3 +1,46 @@ +VALUES( +('Закрыта неуспешно',7,0), +('Закрыта успешно',6,100), +('Договор подписан',5,100), +('Договор на подписании',15,90), +('Договор на согласовании',12,70), +('Тестирование',8,50), +('Отправлено ТКП',10,20), +('Внутреннее согласование',37,10), +('Проработка решения',4,10), +('Сбор потребностей',1,0) +) as status(status, status_id, probability_pc) + +Закрыта неуспешно +7 +0 +Закрыта успешно +6 +100 +Договор подписан +5 +100 +Договор на подписании +15 +90 +Договор на согласовании +12 +70 +Тестирование +8 +50 +Отправлено ТКП +10 +20 +Внутреннее согласование +37 +10 +Проработка решения +4 +10 +Сбор потребностей +1 +0 2025-07-10 15:08:02 Оказывается, есть разница между "0 с 1 июля" и "ничего с 1 июля" - в текущей версии 0 с вероятностью 100 непрозрачен, а нулл с вероятностью 100 получается полностью прозрачен. Либо здесь несимметрия по времени должна быть diff --git a/income_daily_rpt.cfm b/income_daily_rpt.cfm index b723d08..4c089f1 100644 --- a/income_daily_rpt.cfm +++ b/income_daily_rpt.cfm @@ -176,6 +176,7 @@ from ( where iiv.specification_item_uid=si.specification_item_uid AND ia.agreement_version < siv.agreement_version AND ia.is_actual /*именно действующее соглашение, принимаемое за факт*/ + /*а почему тут дату не проверяем ВПР*/ ) ) left outer join specification_item_version siv0 on (siv0.specification_item_uid=si.specification_item_uid