Загрузка данных


CREATE OR REPLACE FUNCTION ourpension.f_reconciliation_of_operations(db date, de date, p_fund_id integer DEFAULT 1)
 RETURNS TABLE(num integer, title text, beg numeric, pfr_in numeric, npf_in numeric, other_in numeric, total_in numeric, pension numeric, assignee numeric, pens_ass numeric, pfr_out numeric, npf_out numeric, total_out numeric, returns numeric, acc_red numeric, acc_res_red numeric, gar numeric, id numeric, ops_to_pds numeric, comission numeric, from_rops_to_ops_pds numeric, "end" numeric, total_cr numeric, total_db numeric, total_cr_db numeric, "check" numeric)
 LANGUAGE plpgsql
 SET plan_cache_mode TO 'force_custom_plan'
 SET work_mem TO '256MB'
 SET hash_mem_multiplier TO '2'
 SET jit TO 'off'
AS $function$

 begin



  	drop table if exists selected_funds;

	drop table if exists temp_transactions;

	drop table if exists acc_types_agg_in_group_temp;

	drop table if exists oper_types_agg_in_group_temp;

	drop table if exists balance;

	drop table if exists pg_temp.balance_relevant;



 create temp table if not exists acc_types_agg_in_group_temp

 on commit drop as

 with t(group_num , group_type , type_in , type_out, cross_link ) as (

	 values

	 (1,'Н',null,null,null),--Накопление

	 (1,'Р(Е)',null,null,null),--Резерв единовременных выплат

--	 (1,null,'НВ ОПС',null,null),--Начисление выплат (Страховые взносы)

--	 (1,null,'НВ ДПС Г',null,'{2,3,4}'),--Начисление выплат (Взносы софинансирования)

--	 (1,null,'НВ ДПС Л',null,'{2,3,4}'),--Начисление выплат (Добровольные страховые взносы)

--	 (1,null,'НВ ДПС МК',null,null),--Начисление выплат (Материнский капитал)

--	 (1,null,'НВ ПП ДПС МК',null,null),--Начисление выплат правопреемникам (Материнский капитал)

	 (2,'Н',null,'{ДПС МК,ДПС МК ИД}',null),

	 (2,'Р(Е)',null,'{Р(Е) ДПС МК,Р(Е) ДПС МК ИД}',null),

--	 (2,null,'НВ ОПС',null,null),

--	 (2,null,'НВ ДПС Г',null,'{2,3,4}'),

--	 (2,null,'НВ ДПС Л',null,'{2,3,4}'),

--	 (3,null,'НВ ДПС МК',null,null),

	 (3,null,'ДПС МК',null,null),--Материнский капитал

	 (3,null,'ДПС МК ИД',null,null),

	 (3,null,'Р(Е) ДПС МК',null,null),--Резерв единовременных выплат (Материнский капитал)

	 (3,null,'Р(Е) ДПС МК ИД',null,null),

	 (4,'Р ПП',null,null,null),--Резерв выплат правопреемникам

--	 (4,null,'НВ ПП ОПС',null,null),--Начисление выплат правопреемникам (Страховые взносы)

--	 (4,'НВ ПП',null,null,null),--Начисление выплат правопреемникам

--	 (6,null,'НВ ДПС Г',null,'{1}'),

--	 (6,null,'НВ ДПС Л',null,'{1}'),

--	 (6,null,'Р(С)',null,'{1}'),--Резерв срочных выплат (мнемоника типа счета или подгруппы?)

--	 (6,null,'Р(С) ИД',null,'{1}'),

	 (6,null,'Р(С) ОПС',null,'{1}'),

	 (6,null,'Р(С) ОПС ИД',null,'{1}'),

	 (6,null,'Р(С) ДПС Л',null,'{1}'),

	 (6,null,'Р(С) ДПС Л ИД',null,'{1}'),

	 (6,null,'Р(С) ДПС Р',null,'{1}'),

	 (6,null,'Р(С) ДПС Р ИД',null,'{1}'),

	 (6,null,'Р(С) ДПС Г',null,'{1}'),

	 (6,null,'Р(С) ДПС Г ИД',null,'{1}'),

	 (7,null,'НВ ДПС МК',null,'{1}'),

	 (7,null,'НВ ПП ДПС МК',null,'{1}'),

	 (7,null,'Р(С) ДПС МК',null,'{1}'),

	 (7,null,'Р(С) ДПС МК ИД',null,'{1}'),

	 (9,'Р(П)',null,null,null),--Резерв пожизненных выплат (мнемоника типа счета или подгруппы?)

	 (10,null,'Р ОПС',null,null)--,

--	 (10,null,'Р ОПС ИД',null,null)

--как перетекают деньги из мнем в мнем? Н - Р(П) ОПС - НВ ОПС - В ОПС - ВЗ (-> Р(П))

)

 , tt as (

 select * from t

 union all

 select 5, group_type , type_in , type_out, cross_link

 from t

 where group_num in (2,3,4)

 union all

 select 8, group_type , type_in , type_out, cross_link

 from t

 where group_num in (6,7)

 )

 select * from tt

 union all

 select 11, group_type , type_in , type_out, cross_link

 from tt

 where group_num in (5,8,9,10)

 order by group_num, group_type , type_in , type_out, cross_link;



 create temp table if not exists oper_types_agg_in_group_temp

 on commit drop as

 select * from (

	 values

	 (1,'PENSION_SAVINGS_ENROLLMENT',null,null),

	 (2,'PENSION_SAVINGS_ENROLLMENT',null,null),

	 (3,'MANUAL_TEMPORARY',null,null),

	 (3,'ENROLLMENT_OTHER',null,null),

	 (4,'PENSION_SAVINGS_ENROLLMENT',null,null),

	 (4,'MANUAL_TEMPORARY',null,null),

	 (4,'ENROLLMENT_OTHER',null,null),

	 (5,'PAYMENT_SPV',1,null),

	 (5,'PAYMENT_NP',2,null),

	 (5,'PAYMENT_EV',3,null),

	 (5,'ADDITIONAL_PAYMENT_EV',4,null),

	 (6,'PAYMENT_PP',null,null),

	 (6,'ADDITIONAL_PAYMENT_PP',null,null),

	 (7,'PAYMENT_SPV',1,null),

	 (7,'PAYMENT_NP',2,null),

	 (7,'PAYMENT_EV',3,null),

	 (7,'ADDITIONAL_PAYMENT_EV',4,null),

	 (7,'PAYMENT_PP',null,null),

	 (7,'ADDITIONAL_PAYMENT_PP',null,null),

	 (8,'TRANSFER',null,null),

	 (9,'TRANSFER',null,null),

	 (10,'TRANSFER',null,null),

	 (11,'RETURN',null,null),

	 (12,'TRANSFER_TO_ASSIGNEE_RESERVE',null,null),-- гр. Н, Р(Е), Р(ПП)

	 (13,'TRANSFER_TO_RESERVE',null,null),

	 (14,'GUARANTEE_ENROLLMENT',null,null),

	 (14,'GUARANTEE',null,null),

	 (15,'PENSION_INVESTMENT_REVENUE_ENROLLMENT',null,null),

	 (16,'PDS_OPS_ENROLLMENT_OPS',null,null),

	 (16,'PDS_TRANSFER_OPS',null,null),

	 (17,'COMMISSION_NP_FROM_FUND_RESERVE',null,null),

	 (18,'TRANSFER_TO_INSURED_FUND_RESERVE_OPS_PDS',null,null)



) t (group_num , group_type , id , type_out );



 case

  when db is null or de is null then

  return query

  select null:: integer, null:: text, null:: numeric, null:: numeric, null:: numeric, null:: numeric, null:: numeric, null:: numeric, null:: numeric, null:: numeric, null:: numeric, null:: numeric,

  null:: numeric, null:: numeric, null:: numeric, null:: numeric, null:: numeric, null:: numeric, null:: numeric, null:: numeric, null:: numeric, null:: numeric, null:: numeric, null:: numeric, null:: numeric, null:: numeric;

 else



	raise notice 'start create temp table selected_funds %', clock_timestamp();

  CREATE TEMP TABLE IF NOT EXISTS selected_funds

    ON COMMIT DROP AS

    WITH

    fund_sharers AS NOT MATERIALIZED (

        SELECT sh.id

        FROM ourpension.contract c

        JOIN ourpension.sharer sh

          ON sh.contract_id = c.id

        WHERE c.fund_id = p_fund_id

    ),

    ops_types AS NOT MATERIALIZED (

        SELECT

            at.id,

            at.mnemonics,

            atg.mnemonics AS group_mnemonics

        FROM back_office.account_type at

        JOIN back_office.account_type_group atg

          ON atg.id = at.account_type_group_id

        WHERE at.service_type = 'OPS'

    )

    SELECT

        a.id,

        ot.mnemonics,

        ot.group_mnemonics

    FROM fund_sharers fs

    JOIN back_office.account a

      ON a.owner_sharer_id = fs.id

    JOIN ops_types ot

      ON ot.id = a.account_type_id



    UNION ALL



    SELECT

        a.id,

        at.mnemonics,

        atg.mnemonics AS group_mnemonics

    FROM back_office.account a

    JOIN back_office.account_type at

      ON at.id = a.account_type_id

    JOIN back_office.account_type_group atg

      ON atg.id = at.account_type_group_id

    WHERE a.owner_entity_id = p_fund_id

      AND a.account_type_id IN (41);



	--296 федерация

	CREATE INDEX selected_funds_idx ON selected_funds(id, mnemonics, group_mnemonics);

	ANALYZE selected_funds; -- 24M строк: актуальная статистика критична для JOIN

	raise notice 'end create temp table selected_funds %', clock_timestamp();



	raise notice 'start insert into temp_transactions %', clock_timestamp();



  create temp table if not exists temp_transactions on commit drop as

	select *

  from back_office.transaction t

  where t.effective_date between $1::date and $2::date;



--  (select ca.owner_sharer_id, ca.owner_entity_id, ca.owner_individual_id, t.value acc_type_value, 'credit' direction, t.effective_date, sf.mnemonics,  sf.group_mnemonics

--  from back_office."transaction" t

--    join back_office."account" ca on ca.id = t.credit_account_id

--    join selected_funds sf on sf.id = ca.id

--      join back_office.operation o on o.id = t.operation_id

--      join back_office.operation_type ot on ot.id = o.operation_type_id--01.12.2025

--      join oper_types_agg_in_group_temp temp_1 on temp_1.group_type = ot.code--01.12.2025

--	  join acc_types_agg_in_group_temp acc_temp on --01.12.2025

--	          case when acc_temp.group_type is null then true else acc_temp.group_type = sf.mnemonics end--01.12.2025

--	      and case when acc_temp.type_in is null then true else acc_temp.type_in = sf.mnemonics end--01.12.2025

--	      and case when acc_temp.type_out is null then true else sf.mnemonics <> all(acc_temp.type_out::text[]) end--01.12.2025

--  where t.effective_date <= de

--     and o.approved is not null /*Авторизована*/

--   and o.deleted is null /*Не удалена*/

--   and o.revoked is null /*Не отозвана*/

--

--    union all

--

--  select da.owner_sharer_id, da.owner_entity_id, da.owner_individual_id, -t.value acc_type_value, 'debit' direction, t.effective_date, sf.mnemonics,  sf.group_mnemonics

--  from back_office."transaction" t

--    join back_office."account" da on da.id = t.debit_account_id

--    join selected_funds sf on sf.id = da.id

--      join back_office.operation o on o.id = t.operation_id

--      join back_office.operation_type ot on ot.id = o.operation_type_id--01.12.2025

--      join oper_types_agg_in_group_temp temp_1 on temp_1.group_type = ot.code--01.12.2025

--	  join acc_types_agg_in_group_temp acc_temp on --01.12.2025

--	          case when acc_temp.group_type is null then true else acc_temp.group_type = sf.mnemonics end--01.12.2025

--	      and case when acc_temp.type_in is null then true else acc_temp.type_in = sf.mnemonics end--01.12.2025

--	      and case when acc_temp.type_out is null then true else sf.mnemonics <> all(acc_temp.type_out::text[]) end--01.12.2025

--  where t.effective_date <= de

--     and o.approved is not null /*Авторизована*/

--   and o.deleted is null /*Не удалена*/

--   and o.revoked is null /*Не отозвана*/

--  );



--	CREATE INDEX temp_transactions_idx ON temp_transactions(effective_date,group_mnemonics,mnemonics,direction,acc_type_value);



	raise notice 'end insert into temp_transactions %', clock_timestamp();

	raise notice 'start balance %', clock_timestamp();



    -- V2: сначала отбираем актуальные срезы остатков из balance,

    -- а уже потом соединяем их с ~24 млн selected_funds.

    -- У balance ~454 млн строк, но уникальных account_id значительно меньше.

    -- Этот шаг предотвращает план с миллионами пробных обращений к balance

    -- по каждому ID selected_funds. Не используем DISTINCT: сохраняем

    -- все строки истории, в т.ч. возможные пересечения периодов.

    raise notice 'start balance_relevant %', clock_timestamp();

    CREATE TEMP TABLE balance_relevant ON COMMIT DROP AS

    SELECT

        b.account_id,

        b.total_credit - b.total_debit AS total,

        (($1::date - 1) BETWEEN b.start_date AND b.end_date) AS for_beg,

        ($2::date BETWEEN b.start_date AND b.end_date) AS for_end

    FROM back_office.balance b

    WHERE (($1::date - 1) BETWEEN b.start_date AND b.end_date)

       OR ($2::date BETWEEN b.start_date AND b.end_date);



    ANALYZE balance_relevant;

    raise notice 'end balance_relevant %', clock_timestamp();



    -- Сохраняем исходные соответствия счетов группам и кратность строк.

    -- FILTER вычисляет начальный и конечный остаток одним агрегированием.

    raise notice 'start balance_aggregate %', clock_timestamp();

    CREATE TEMP TABLE balance ON COMMIT DROP AS

    SELECT agg.mnem_gr, v.total, v."date"

    FROM (

        SELECT

            acc_temp.group_num AS mnem_gr,

            SUM(br.total) FILTER (WHERE br.for_beg) AS total_beg,

            COUNT(*) FILTER (WHERE br.for_beg) AS count_beg,

            SUM(br.total) FILTER (WHERE br.for_end) AS total_end,

            COUNT(*) FILTER (WHERE br.for_end) AS count_end

        FROM balance_relevant br

        JOIN selected_funds sf

          ON sf.id = br.account_id

        JOIN acc_types_agg_in_group_temp acc_temp

          ON (acc_temp.group_type IS NULL OR acc_temp.group_type = sf.group_mnemonics)

         AND (acc_temp.type_in IS NULL OR acc_temp.type_in = sf.mnemonics)

         AND (acc_temp.type_out IS NULL OR sf.mnemonics <> ALL(acc_temp.type_out::text[]))

        GROUP BY acc_temp.group_num

    ) agg

    CROSS JOIN LATERAL (

        VALUES

            (agg.total_beg, 'beg'::text, agg.count_beg),

            (agg.total_end, 'end'::text, agg.count_end)

    ) v(total, "date", cnt)

    WHERE v.cnt > 0;



    raise notice 'end balance_aggregate %', clock_timestamp();



	raise notice 'end balance %', clock_timestamp();



	raise notice 'start return query start %', clock_timestamp();



  return query

  with anker as (

	     select *

	      from unnest ((select '{'||string_agg(n::text,',')||'}' from pg_catalog.generate_series(1,11)  gs(n))::int[],

	        array['СПН, учтенные на счетах ЗЛ (кроме умерших ЗЛ)',

	            'СПН, учтенные на счетах ЗЛ (кроме МК)',

	            'Материнский капитал, учтенный на счетах ЗЛ',

	            'СПН, учтенные на счете умерших ЗЛ',

	            'Итого СПН, учтенные на счетах',

	            'Резерв СПВ (выплаты без учета МК)',

	            'Резерв СПВ (выплаты за счет материнского капитала)',

	            'Резерв СПВ',

	            'ВР',

	            'РОПС',

	            'Итого ПН']) gs(num,title)

	    )

    , deposit as (--работает

	      select

	      acc_temp.group_num as mnem_gr,

	      string_agg(distinct sf.mnemonics,', ') ,

	      string_agg(distinct sf.group_mnemonics,', ') ,

	      t_temp.group_num as oper_gr,

	      sum(case when f.name_in_pfr in ('ПФР','СФР') then t.value else 0 end) pfr_in,

	      sum(case when f.name_in_pfr not in ('ПФР','СФР') then t.value else 0 end) npf_in,

	      sum(case when t_temp.group_num = '3' then t.value else 0 end) other_in,

	      sum(t.value) total_in

	    from selected_funds sf

	      join back_office.account da on sf.id = da.id

	    	join temp_transactions t on t.credit_account_id = da.id

	--      join back_office.account_type at on at.id = da.account_type_id

	--      join back_office.account_type_group atg on at.account_type_group_id = atg.id

	      join acc_types_agg_in_group_temp acc_temp on

	              case when acc_temp.group_type is null then true else acc_temp.group_type = sf.group_mnemonics end

	          and case when acc_temp.type_in is null then true else sf.mnemonics = acc_temp.type_in end

	          and case when acc_temp.type_out is null then true else sf.mnemonics <> all(acc_temp.type_out::text[]) end

	      join back_office.operation o on o.id = t.operation_id

	      join back_office.operation_type ot on ot.id = o.operation_type_id

	      join oper_types_agg_in_group_temp t_temp on t_temp.group_type = ot.code and t_temp.group_num in ('1','2','3','4')

	      join back_office.incoming_order_operation iop on iop.operation_id = t.operation_id

	      join back_office.incoming_order io on iop.incoming_order_id = io.id

	        and io.service_type = 'OPS'

	      join ourpension.entity e on io.payer_entity_id = e.id

	      join ourpension.fund f on f.entity_id = e.id

	    where t.effective_date between $1::date and $2::date

	     and o.approved is not null /*Авторизована*/

	   and o.deleted is null /*Не удалена*/

	   and o.revoked is null /*Не отозвана*/

	    group by acc_temp.group_num,t_temp.group_num

	    order by acc_temp.group_num,t_temp.group_num

    )

  	, transfert as (-- работает

	      select

	      acc_temp.group_num as mnem_gr,

	      string_agg(distinct sf.mnemonics,', ') ,

	      string_agg(distinct sf.group_mnemonics,', ') ,

	      t_temp.group_num as oper_gr,

	      sum(case when f.name_in_pfr in ('ПФР','СФР') then t.value else 0 end) pfr_out,

	      sum(case when f.name_in_pfr not in ('ПФР','СФР') then t.value else 0 end) npf_out,

	      sum(t.value) total_out

	    from selected_funds sf

	      join back_office.account da on sf.id = da.id

	    	join temp_transactions t on t.debit_account_id = da.id

	      join acc_types_agg_in_group_temp acc_temp on

	              case when acc_temp.group_type is null then true else acc_temp.group_type = sf.group_mnemonics end

	          and case when acc_temp.type_in is null then true else sf.mnemonics = acc_temp.type_in end

	          and case when acc_temp.type_out is null then true else sf.mnemonics <> all(acc_temp.type_out::text[]) end

	      join back_office.operation o on o.id = t.operation_id

	      join back_office.operation_type ot on ot.id = o.operation_type_id

	      join oper_types_agg_in_group_temp t_temp on t_temp.group_type = ot.code and t_temp.group_num in ('8','9','10')

	      join back_office.account ca on t.credit_account_id = ca.id

	      join ourpension.entity e on ca.owner_entity_id = e.id

	      join ourpension.fund f on f.entity_id = e.id

	    where t.effective_date between $1::date and $2::date

	     and o.approved is not null /*Авторизована*/

	   and o.deleted is null /*Не удалена*/

	   and o.revoked is null /*Не отозвана*/

	    group by acc_temp.group_num,t_temp.group_num

	    order by acc_temp.group_num,t_temp.group_num

    )

  	, lets_start as (



  		select

	      acc_temp.group_num as mnem_gr,

	      t_temp.group_num as oper_gr,

	      sum(case when t_temp.group_num = '5' then t.value else 0 end) pension,-- сильная разница в обе стороны

	      sum(case when t_temp.group_num = '6' then t.value else 0 end) assignee,

	      sum(case when t_temp.group_num = '7' then t.value else 0 end) pens_ass,

	      sum(case when t_temp.group_num = '16' then t.value else 0 end) ops_to_pds,--просто жесть а не разница

	      sum(case when t_temp.group_num = '17' then t.value else 0 end) comission,

	      sum(case when t_temp.group_num = '18' then t.value else 0 end) from_rops_to_ops_pds,

	      sum(t.value) sum_value

	    from selected_funds sf

	      join back_office.account da on sf.id = da.id

	    	join temp_transactions t on t.debit_account_id = da.id

	      join acc_types_agg_in_group_temp acc_temp on

	              case when acc_temp.group_type is null then true else acc_temp.group_type = sf.group_mnemonics end

	          and case when acc_temp.type_in is null then true else sf.mnemonics = acc_temp.type_in end

	          and case when acc_temp.type_out is null then true else sf.mnemonics <> all(acc_temp.type_out::text[]) end

	      join back_office.operation o on o.id = t.operation_id

	      join back_office.operation_type ot on ot.id = o.operation_type_id

	      join oper_types_agg_in_group_temp t_temp on t_temp.group_type = ot.code

			and t_temp.group_num in ('5','6','7','11','12','13','14','15','16','17','18')

--	      	and case when acc_temp.cross_link is not null then t_temp.id = any (acc_temp.cross_link::int[]) else true end

	    where t.effective_date between $1::date and $2::date

	     and o.approved is not null /*Авторизована*/

	   and o.deleted is null /*Не удалена*/

	   and o.revoked is null /*Не отозвана*/

	    group by acc_temp.group_num,t_temp.group_num

	    order by acc_temp.group_num,t_temp.group_num



    )

    select gen.*, gen.total_cr+gen.total_db total_cr_db, gen.acc_res_red - (gen.total_cr+gen.total_db) "check"

    from

    (

     select gs.num, gs.title, s0.total beg,

		s1.pfr_in ,s2.npf_in ,s3.other_in ,s4.total_in ,

		s5.pension,s6.assignee,s7.pens_ass,

		s8.pfr_out,s9.npf_out ,s10.total_out ,

		s11.sum_value "returns",

      s12.sum_value acc_red,s13.sum_value acc_res_red,s14.sum_value gar,s15.sum_value id, s19.ops_to_pds, s20.comission, s21.from_rops_to_ops_pds, s16.total "end",0::numeric total_cr, 0::numeric total_db--, s17.total_cr, s18.total_db

     from anker gs

     left join (select * from balance where "date"='beg') s0 on gs.num = s0.mnem_gr

     left join (select *

         from deposit

         where oper_gr = 1) s1 on gs.num = s1.mnem_gr

     left join (select *

         from deposit

         where oper_gr = 2) s2 on gs.num = s2.mnem_gr

     left join (select *

         from deposit

         where oper_gr = 3) s3 on gs.num = s3.mnem_gr

     left join (select *

         from deposit

         where oper_gr = 4) s4 on gs.num = s4.mnem_gr

     left join (select *

         from lets_start

         where oper_gr = 5) s5 on gs.num = s5.mnem_gr

     left join (select *

         from lets_start

         where oper_gr = 6) s6 on gs.num = s6.mnem_gr

     left join (select *

         from lets_start

         where oper_gr = 7) s7 on gs.num = s7.mnem_gr

     left join (select *

         from transfert

         where oper_gr = 8) s8 on gs.num = s8.mnem_gr

     left join (select *

         from transfert

         where oper_gr = 9) s9 on gs.num = s9.mnem_gr

     left join (select *

         from transfert

         where oper_gr = 10) s10 on gs.num = s10.mnem_gr

     left join (select *

         from lets_start

         where oper_gr = 11) s11 on gs.num = s11.mnem_gr

     left join (select *

         from lets_start

         where oper_gr = 12) s12 on gs.num = s12.mnem_gr

     left join (select *

         from lets_start

         where oper_gr = 13) s13 on gs.num = s13.mnem_gr

     left join (select *

         from lets_start

         where oper_gr = 14) s14 on gs.num = s14.mnem_gr

     left join (select *

         from lets_start

         where oper_gr = 15) s15 on gs.num = s15.mnem_gr

     left join (select * from balance where "date"='end') s16 on gs.num = s16.mnem_gr

--     left join (select *

--         from (select

--          acc_temp.group_num as mnem_gr,

--          sum(q.acc_type_value) total_cr

--      from acc_types_agg_in_group_temp acc_temp

--      join (select

--         q.direction, q.mnemonics, q.group_mnemonics, sum(q.acc_type_value) acc_type_value, 'start'

--       from temp_transactions q

--       where direction = 'credit'

--       group by q.direction, q.mnemonics, q.group_mnemonics) q on

--              case when acc_temp.group_type is null then true else acc_temp.group_type = q.group_mnemonics end

--          and case when acc_temp.type_in is null then true else acc_temp.type_in = q.mnemonics end

--          and case when acc_temp.type_out is null then true else q.mnemonics <> all(acc_temp.type_out::text[]) end

--      group by acc_temp.group_num)) s17 on gs.num = s17.mnem_gr

--     left join (select *

--         from (select

--          acc_temp.group_num as mnem_gr,

--          sum(q.acc_type_value) total_db

--      from acc_types_agg_in_group_temp acc_temp

--      join (select

--         q.direction, q.mnemonics, q.group_mnemonics, sum(q.acc_type_value) acc_type_value, 'start'

--       from temp_transactions q

--       where direction = 'debit'

--       group by q.direction, q.mnemonics, q.group_mnemonics) q on

--              case when acc_temp.group_type is null then true else acc_temp.group_type = q.group_mnemonics end

--          and case when acc_temp.type_in is null then true else acc_temp.type_in = q.mnemonics end

--          and case when acc_temp.type_out is null then true else q.mnemonics <> all(acc_temp.type_out::text[]) end

--      group by acc_temp.group_num)) s18 on gs.num = s18.mnem_gr

     left join (select *

         from lets_start

         where oper_gr = 16) s19 on gs.num = s19.mnem_gr

     left join (select *

         from lets_start

         where oper_gr = 17) s20 on gs.num = s20.mnem_gr

     left join (select *

         from lets_start

         where oper_gr = 18) s21 on gs.num = s21.mnem_gr

     order by num

    ) gen

    ;

	raise notice 'end return query %', clock_timestamp();

  end case;



  	drop table if exists selected_funds;

	drop table if exists temp_transactions;

	drop table if exists acc_types_agg_in_group_temp;

	drop table if exists oper_types_agg_in_group_temp;

	drop table if exists balance;

	drop table if exists pg_temp.balance_relevant;



 END;

$function$