Точно так же я не могу многое сделать с тех пор из этого запроса. Но из описания звучит и выглядит так, будто вы хотите записать текущую ежедневную историю, содержащую первую (предполагаемую из комментариев в запросе) и последнюю транзакцию (предполагаемую из описания и опубликованных результатов? () Для каждого клиента в новую таблицу. Идея, лежащая в основе календарной таблицы, однако этого недостаточно, и я не буду просто определять свое собственное. Подход заключается в том, чтобы зафиксировать минимальную и максимальную дату транзакции по клиенту, если даты предшествуют или равны указанной дате (run_date). Это позволяет перезапустить на один день, если это необходимо, или если он не запускается в определенный день. Затем результат вставляется в таблицу истории.
-- create the history table
create table client_tran_date_hist(
run_date date
, client_id integer
, first_tran_date date
, last_tran_date date);
alter table client_tran_date_hist add constraint client_tran_date_hist_pk primary key (client_id, run_date);
Заполняет таблицу истории на указанную дату (примечание: процедура НЕ откатывается при повторном запуске на предыдущую дату.)
-- Procedure to populate history table for specified date (note: function returns void = procedure -- well almost)
create or replace function client_tran_date_history(run_date_in date default current_date)
returns void
language sql strict
as $$
insert into client_tran_date_hist( run_date, client_id, first_tran_date, last_tran_date)
select run_date_in
, cid -- client id
, min_dt -- first tran date
, max_dt -- last tran dats
from ( -- get first and last tran date for each client
select run_date_in
, client_id cid
, min(created_at)::date min_dt
, max(created_at)::date max_dt
from raw_transactions
where created_at::date <= run_date_in
group by client_id
) r
where not exists ( -- except existing clients without dates a changed
select null
from client_tran_date_hist
where run_date = run_date_in
and client_id = cid
and first_tran_date = min_dt
and last_tran_date = max_dt
)
on conflict on constraint client_tran_date_hist_pk -- when clients already exists
do update -- updated both dates
set first_tran_date = excluded.first_tran_date
, last_tran_date = excluded.last_tran_date;
$$;
Процедура создания отчета об истории транзакций.
-- function to generate report
create or replace function client_tran_date_history_report (start_date_in date default current_date
,end_date_in date default current_date
)
returns table ( run_date date
, last_transaction_date date
, client text
)
language sql strict
as $$
select h.run_date
, h.last_tran_date
, c.name
from client_tran_date_hist h
join clients c
on (c.id = h.client_id)
where run_date between start_date_in and end_date_in;
$$;
Процедура испытаний. Фактические даты и таблица клиентов в функции отчета должны быть предоставлены вашей системой.
do $$
begin
perform client_tran_date_history(run_date_in => date '2020-01-06');
perform client_tran_date_history(run_date_in => date '2020-01-13');
perform client_tran_date_history(run_date_in => date '2020-01-20');
perform client_tran_date_history(run_date_in => date '2020-02-20');
end ;
$$;
select * from client_tran_date_history_report (start_date_in => '2020-01-01')
where client = 'Alex'
order by client, run_date;
Я надеюсь, что это даст вам правильное направление для продолжения.