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