Выбор самой последней записи в ячейке временной метки

#sql #postgresql #datetime #inner-join #greatest-n-per-group

#sql #postgresql #дата и время #внутреннее соединение #наибольшее число пользователей на группу

Вопрос:

У меня есть эти две таблицы:

 User:
=======================
  id  |  Name | Email 
=======================
  1   | User-A| a@mail
  2   | User-B| b@mail
=======================

Entry:
=================================================
  id  |  agree |       createdOn        | userId
=================================================
  1   | true   | 2020-11-10 19:22:23    |   1
  2   | false  | 2020-11-10 22:22:23    |   1
  3   | true   | 2020-11-11 12:22:23    |   1
  4   | true   | 2020-11-04 22:22:23    |   2
  5   | false  | 2020-11-12 02:22:23    |   2
================================================
  

Мне нужно получить следующий результат:

 
=============================================================
  Name    |   Email    |   agree     |       createdOn           
=============================================================
 User-A   |  a@mail    |   true      |  2020-11-11 22:22:23
 User-B   |  b@mail    |   false     |  2020-11-12 02:22:23
=============================================================
  

Выполняемый мной запрос Postgres:

 select distinct on (e."createdOn", u.id)
u.id , e.id ,u."Name" , u.email, e.agree, e."createdOn" from "user" u
inner join public.entry e on u."id" = e."userId"
order by "createdOn" desc
  

Но проблема в том, что он возвращает все записи после выполнения соединения! где мне нужна только самая последняя запись в createdOn ячейке.

Комментарии:

1. distinct on (u.id) ?

Ответ №1:

Вам нужна последняя запись для каждого пользователя. Для этого вам нужен идентификатор пользователя в distinct on предложении, и никакой другой столбец. Это гарантирует одну строку в результирующем наборе для каждого пользователя.

Затем вам нужно поместить этот столбец первым в order by предложении, за которым следует createdOn desc . Это разрывает связи и решает, какая строка будет сохранена в каждой группе:

 select distinct on (u.id) u.id , e.id ,u."Name" , u.email, e.agree, e."createdOn" 
from "user" u
inner join public.entry e on u."id" = e."userId"
order by u.id, "createdOn" desc
  

Ответ №2:

Вы также можете использовать row_number для выбора последних строк, а затем выполнить объединение

 SELECT * FROM USER A 
LEFT JOIN (
  SELECT * FROM (
    SELECT *,ROW_NUMBER() OVER(PARTITION BY USERID ORDER BY CREATEDON DESC) AS RN
      FROM ENTRY
  ) K WHERE RN = 1
) B
ON A.ID = B.USERID
  

Ответ №3:

Попробуйте использовать функцию createdon = max(createdon). Группировка по пользователю