ORACLE:SQL 查询以提取每个类别的最后输入日期

ORACLE: SQL Query to extract last entry date per category

通过这个查询

select  cust_id, start_time, category from (
select * from events order by category  asc
)where cust_id= '860730'
AND start_time BETWEEN TO_DATE('07/11/2020 00:00:00', 'DD/MM/YYYY hh24:mi:ss') AND TO_DATE('08/11/2020 00:00:00', 'DD/MM/YYYY hh24:mi:ss')

我得到:

    cust_id    start_time      category
    860730  07-NOV-20 07:04:00  1
    860730  07-NOV-20 08:40:36  1
    860730  07-NOV-20 08:49:03  1
    860730  07-NOV-20 08:56:22  1
    860730  07-NOV-20 07:45:53  2
    860730  07-NOV-20 07:56:44  2
    860730  07-NOV-20 08:49:15  2
    860730  07-NOV-20 08:59:37  2
    860730  07-NOV-20 09:10:52  2
    860730  07-NOV-20 11:34:49  3
    860730  07-NOV-20 08:37:10  3
    860730  07-NOV-20 09:00:21  3
    860730  07-NOV-20 13:05:53  3
    860730  07-NOV-20 15:55:34  3
    860730  07-NOV-20 16:07:46  3
    860730  07-NOV-20 16:47:08  4
    860730  07-NOV-20 17:37:27  4
    860730  07-NOV-20 18:59:35  4

如何按类别只提取最近的记录?最后得到这个结果:

860730  07-NOV-20 08:56:22  1
860730  07-NOV-20 09:10:52  2
860730  07-NOV-20 16:07:46  3
860730  07-NOV-20 18:59:35  4

您问题的基本答案是使用 row_number()。但请注意我对查询所做的其他更改:

select cust_id, start_time, category 
from (select e.*,
             row_number() over (partition by category order by fme_start_time desc) as seqnum
      from events e
      where cust_id = '860730' and
            fme_start_time >= date '2020-11-07' and
            fme_start_time < date '2020-11-08'
     ) e
where seqnum = 1;

备注:

  • Oracle 支持日期文字。这比将字符串转换为日期更简洁准确。
  • 所有where条件都可以进入子查询。
  • row_number()随心所欲
  • 如果 cust_id 是一个数字——我强烈怀疑——去掉单引号。将数字与数字进行比较,将字符串与字符串进行比较。不要混合类型。

编辑:

实际上,给定你想要的列,聚合更简单:

select cust_id, max(start_time), category 
from events e
where cust_id = '860730' and
       fme_start_time >= date '2020-11-07' and
       fme_start_time < date '2020-11-08'
group by cust_id, category;

如果您需要其他栏目,第一个版本很方便。