Search code examples
sqlpostgresqldategreatest-n-per-groupwindow-functions

Determining first activity for the day per user


I have a table "UserData" with the following information in it:

User    Date    DateTime        Input
1   8/4/2019    8/4/2019 0:55   Request
1   8/4/2019    8/4/2019 0:56   Ticket
1   8/4/2019    8/4/2019 2:08   Submit
1   8/4/2019    8/4/2019 2:21   Submit
2   8/4/2019    8/4/2019 13:10  Submit
2   8/20/2019   8/20/2019 2:10  Ticket
2   8/20/2019   8/20/2019 2:12  Ticket
2   8/20/2019   8/20/2019 2:13  Request
3   8/20/2019   8/20/2019 2:15  Request
3   8/19/2019   8/19/2019 2:16  Ticket
3   6/12/2020   6/12/2020 2:22  Submit
3   6/12/2020   6/12/2020 2:26  Submit
3   6/12/2020   6/12/2020 3:26  Ticket

I'm looking to return the first input from each user (based on time) but only on the newest day. So my output would be something like this:

User    DateTime    Input
1   8/4/2019 0:55   Request
2   8/20/2019 2:10  Ticket
3   6/12/2020 2:22  Submit

I'm thinking that I need to assign a rank to each date but not really sure where to start on this one.


Solution

  • With row_number() window function:

    select t."User", t."Date", t."DateTime", t."Input"
    from (
      select *, row_number() over (partition by "User" order by "Date" desc, "DateTime") rn
      from UserData
    ) t
    where t.rn = 1
    

    For every user the row are sorted by "Date" descending to find the latest date and then by "DateTime" ascending to get the 1st input of that day.
    See the demo.
    Results:

    | User | Date       | DateTime         | Input   |
    | ---- | ---------- | ---------------- | ------- |
    | 1    | 2019-08-04 | 2019-08-04 00:55 | Request |
    | 2    | 2019-08-20 | 2019-08-20 02:10 | Ticket  |
    | 3    | 2020-06-12 | 2020-06-12 02:22 | Submit  |