检索表中不同ID的最大日期

时间:2019-09-09 16:35:12

标签: sql oracle greatest-n-per-group

我有包含以下数据的表ABC

Id  Name    Date      Execution id 
--  ----  ---------  -------------
1    AA   09SEP2019      11
1    AA   08SEP2019      22
1    AA   07SEP2019      33
2    BB   09SEP2019      44
2    BB   08SEP2019      55
2    BB   07SEP2019      66

我想获取表中每个唯一ID的最大日期。因此结果集必须如下所示

Id Name     Date     Execution id 
-- ----  ---------  -------------
1   AA   09SEP2019      11
2   BB   09SEP2019      44

返回我需要的结果的查询

WITH MaxDate as (
   SELECT Id,Name,Max(Date) from ABC group by Id,Name
)
SELECT view1.*, view2.exection_id
from
       MaxDate view1,
       ABC     view2
WHERE
       view1.date=view2.date and
       view1.name=view2.name;

我不喜欢这样获取唯一ID的最长日期。可能还有另一种方法吗?可能有更简单的方法吗?

3 个答案:

答案 0 :(得分:3)

一种方法是使用RANK

WITH cte AS (
  SELECT ABC.*, RANK() OVER(PARTITION BY Id,Name ORDER BY Date DESC) rnk
  FROM ABC 
)
SELECT *
FROM cte
WHERE rnk = 1
ORDER BY id;

答案 1 :(得分:3)

只要您只想保留一列或少量列,就可以在一个级别的查询中使用keep dense_rank last来做到这一点:

select id,
       max(name) keep (dense_rank last order by date_) as name,
       max(date_) as date_,
       max(execution_id) keep (dense_rank last order by date_) as execution_id
from abc
group by id
order by id;

如果ID和名称并不总是相同,并且您希望名称也以最新日期为准,则使用相同的模式:

contenteditable

与您的样本数据得到相同的结果。

有很多列,使用带有排名功能和过滤器(如@Lukasz所示)的子查询(CTE或内联视图)可能更简单。

答案 2 :(得分:1)

不存在:

select t.* from ABC t
where not exists (
  select 1 from ABC
  where "Id" = t."Id" and "Name" = t."Name" and "Date" > t."Date"
)

我之所以使用and name = t.name是因为您在代码中有了它。
如果不需要,可以将其删除。
请参见demo
结果:

Id | Name | Date      | Execution id
-: | :--- | :---------| -----------:
 1 | AA   | 09-SEP-19 |           11
 2 | BB   | 09-SEP-19 |           44