Select 具有最新时间戳且未更改原始顺序的唯一行

Select unique rows with latest timestamp without changing original order

假设我有以下查询:

SELECT id, name, registration_date
FROM users 
ORDER BY registration_date DESC nulls last;

这导致:

id     name           registration_date
-----------------------------------------------
1a     John Doe       2020-08-21 17:00:41+0000
2a     Joe Darwin     2020-07-21 20:14:10+0000
3a     Jim Lee        2020-07-15 16:14:10+0000

我有另一个 table activity,其中每个用户登录时有多个记录:

例如

id   user_id   last_active
----------------------------------------
1.   1a        2021-05-18 16:14:01+0000
2.   1a        2021-05-17 10:14:01+0000
3.   2a        2021-05-21 12:14:01+0000
4.   2a        2021-05-19 12:14:01+0000
5.   3a        2021-04-17 00:00:01+0000 
6.   3a        2021-03-01 00:00:01+0000 

我需要将此 table 连接到每个用户的 select 最近的 last_active 时间戳。我可以通过以下查询来完成:

SELECT DISTINCT ON(u.id) u.id, u.name, u.registration_date, a.last_active
FROM users
LEFT JOIN activity a ON u.id = a.user_id
ORDER BY u.id, registration_date DESC nulls last;

但是,这改变了原始结果的原始顺序。我不想按 u.id 排序——我需要按 registration_date 排序查询,只需为具有最新 last_active 日期的每一行添加另一列。我怎样才能做到这一点?

莫因,

我以前遇到过同样的问题,我通过使用行号来保存它。 因此,在第一步中,您将创建一个包含最新登录信息的唯一列表,然后您可以加入该列表。

SELECT * FROM(
SELECT
 ROW_NUMBER() OVER (PARTITION BY user_id order by last_active desc) oNR, 
 User_ID,
 last_Active
FROM activity
)s 
WHERE s.oNR = 1 

现在您可以将此加入您的用户

SELECT distinct on(u.id) u.id, u.name, u.registration_date, a.last_active
FROM users
left join 
(
SELECT * FROM(
SELECT
 ROW_NUMBER() OVER (PARTITION BY user_id order by last_active desc) oNR, 
 User_ID,
 last_Active
FROM activity
)s 
WHERE s.oNR = 1 

)


a
on u.id = a.user_id
order by u.id, registration_date desc nulls last;

抱歉格式错误。

此致。

只需按照 DISTINCT ON 的要求对其进行排序,然后 re-sort 按照所需的输出顺序对其进行排序。您将需要添加一个子查询来添加另一个 ORDER BY。

select * from (
  SELECT distinct on(u.id) u.id, u.name, u.registration_date, a.last_active
  FROM users
  left join activity a
  on u.id = a.user_id
  order by u.id, a.last_active desc nulls last
) foo order by registration_date desc nulls last;