获取每组的第一条和最后一条记录

时间:2021-06-27 15:19:29

标签: sql postgresql

我有 2 张桌子,比如

enter image description here

enter image description here

我的输出应该是这样的。基本上,每个 user_unique_access_id 的最新和第一个状态以及时间戳

enter image description here

我尝试了以下查询,但我的输出有重复的记录。

select
    distinct u.user_unique_access_id,
    first_value(ul.status) over (partition by u.user_unique_access_id
order by
    ul.created_timestamp asc) as first_status,
    min(ul.created_timestamp) as first_created_at,
    first_value(ul.status) over (partition by u.user_unique_access_id
order by
    ul.created_timestamp desc) as current_status,
    max(ul.created_timestamp) as last_created_at
from
    public.users u
join public.user_location ul on
    u.user_key = ul.user_key
group by
    u.user_unique_access_id,
    u.user_name,
    ul.status,
    ul.created_timestamp ;

enter image description here

DDL 和 DML 语句

create table public.users ( user_key serial primary key, user_name varchar(20), user_unique_access_id varchar(20) );

create table public.user_location( user_key bigint not null, STATUS VARCHAR (512) not null, CREATED_TIMESTAMP timestamp not null, foreign key (user_key) references public.users (user_key) );

insert
    into
    public.users ( user_unique_access_id, user_name)
values('ABC_1', 'ABC');

insert
    into
    public.users ( user_unique_access_id, user_name)
values('ABC_2', 'ABC');

insert
    into
    public.user_location (user_key, status, created_timestamp)
values(1, 'Entrance', current_timestamp);

insert
    into
    public.user_location (user_key, status, created_timestamp)
values(1, 'Building A', current_timestamp);

insert
    into
    public.user_location (user_key, status, created_timestamp)
values(1, 'Building B', current_timestamp);

insert
    into
    public.user_location (user_key, status, created_timestamp)
values(1, 'Exit', current_timestamp);

insert
    into
    public.user_location (user_key, status, created_timestamp)
values(2, 'Entrance', current_timestamp);

insert
    into
    public.user_location (user_key, status, created_timestamp)
values(2, 'Building A', current_timestamp);

1 个答案:

答案 0 :(得分:1)

您可以使用 DISTINCT ON 获取“第一条”和“最后一条”记录。在两个派生表中使用它(一个用于“第一个”记录,一个用于“最后一个”记录)并将它们连接到 users

SELECT u.user_unique_access_id,
       f.status,
       f.created_timestamp,
       l.status,
       l.created_timestamp
       FROM users u
            LEFT JOIN (SELECT DISTINCT ON (ul.user_key)
                              ul.user_key,
                              ul.status,
                              ul.created_timestamp
                              FROM user_location ul
                              ORDER BY ul.user_key ASC,
                                       ul.created_timestamp DESC) f
                      ON f.user_key = u.user_key
            LEFT JOIN (SELECT DISTINCT ON (ul.user_key)
                              ul.user_key,
                              ul.status,
                              ul.created_timestamp
                              FROM user_location ul
                              ORDER BY ul.user_key ASC,
                                       ul.created_timestamp ASC) l
                      ON l.user_key = u.user_key;

(我会链接一个 db<>fiddle 但你的 DML 是非常无用的,因为时间戳都是一样的。)

相关问题