(SQL)创建连续的最后一个事务表

(SQL)创建连续的最后一个事务表,sql,postgresql,sequence,greatest-n-per-group,Sql,Postgresql,Sequence,Greatest N Per Group,我有一个包含客户交易的表,我想创建一个表: Day Last Transaction Client 2020-01-01 2020-01-01 Alex <- Client first transaction 2020-01-02 2020-01-01 Alex 2020-01-03 2020-01-03 Alex <- New transaction ..... 每天我都想知道每个客户的最后一笔交易

我有一个包含客户交易的表,我想创建一个表:

Day          Last Transaction  Client
2020-01-01   2020-01-01        Alex   <- Client first transaction
2020-01-02   2020-01-01        Alex
2020-01-03   2020-01-03        Alex   <- New transaction
.....
每天我都想知道每个客户的最后一笔交易

我不知道你那复杂的问题与你的问题有什么关系。假设列
id
代表客户,并且
creation\u date
是每个事务的时间戳,您可以使用
distinct on
执行此操作,如下所示:

select distinct on (id, creation_date::date) 
    id, 
    creation_date::date transaction_day, 
    creation_date transaction_date
from raw_transactions
order by id, creation_date::date, creation_date desc

同样地,我也不能从这个问题中得到太多的帮助。但是从描述听起来和看起来,您希望捕获一个正在运行的每日历史记录,其中包含第一个事务(根据查询中的注释假设)和最后一个事务(根据描述和发布的结果假设)()为每个客户创建一个新表。我想这是日历表背后的想法。但是,这是不够的,没有定义,我只创建自己的表。
该方法是通过客户端捕获最小和最大事务日期,其中日期早于或等于指定日期(运行日期)。这允许在必要时重新运行一天,或者在某个日期未运行。然后将结果插入历史记录表

-- 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);
填充指定日期的历史记录表(注意:如果重新运行之前的日期,例程不会向前滚动。)

测试过程。报告函数中的实际日期和客户表需要由系统提供

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; 
我希望这能为你提供正确的方向

-- 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;