Select 从 Oracle 中的 table 的 max(effectiveDate) 起最多 2 年的记录

Select records that are upto 2 years old from the max(effectiveDate) from a table in Oracle

我有一个查询,其中 returns ID、effectiveDate 和许多其他列。现在我需要过滤此结果以获取每个 ID 从最近生效日期起最多 2 年的记录。

Table有类似下面的数据

ID |       EffectiveDate   | Col3 |     Col4 | ........
____________________________________________________________
1  |       2020-09-30      |
1  |       2019-09-30      |
1  |       2018-09-30      |
1  |       2018-03-31      |
1  |       2017-09-30      |
2  |       2019-03-31      |
2  |       2018-03-31      |
2  |       2017-03-31      |
3  |       2015-06-30      |
3  |       2015-03-31      |
3  |       2014-12-31      |
3  |       2012-06-30      |

我希望输出为

ID |       EffectiveDate   | Col3      Col4 ........
____________________________________________________________
1  |       2020-09-30      |
1  |       2019-09-30      |
1  |       2018-09-30      |
2  |       2019-03-31      |
2  |       2018-03-31      |
2  |       2017-03-31      |
3  |       2015-06-30      |
3  |       2015-03-31      |
3  |       2014-12-31      |

我试过以下方法

select A.* from table A
inner join
(select ID, col3, col4, max(effectivedate) as MaxDate
from table A
group by ID, col3, Col4 ) B
on A.ID = B.ID
where (B.Maxdate - A.effectiveDate) < 740;

但是这个查询returns所有的记录,没有过滤任何东西。这也是抛出交叉连接结果。请帮忙!

使用window 函数。您的文本指定了每个 id:

的最大值
select a.*
from (select a.*, max(efectivedate) over (partition by id) as max_ed
      from a
     ) a
where effectivedate >= max_ed - interval '740' day;

(注意:730 更有意义。)

如果您希望按查询建议的 id/col3/col4 使用此选项,请在 partition by.

中使用所有三个

如果是“2年”,那就是2年,而不是740天。

SQL> with test (id, efdate) as
  2    (select 1, date '2020-09-30' from dual union all
  3     select 1, date '2019-09-30' from dual union all
  4     select 1, date '2018-09-30' from dual union all
  5     select 1, date '2017-09-30' from dual union all
  6     select 2, date '2019-03-31' from dual union all
  7     select 2, date '2018-03-31' from dual union all
  8     select 2, date '2017-03-31' from dual
  9    ),
 10  tmp as
 11    (select id, efdate, max(efdate) over (partition by id) maxdate
 12     from test
 13    )
 14  select t.id, t.efdate
 15  from test t join tmp m on t.id = m.id and t.efdate = m.efdate
 16  where t.efdate >= add_months(m.maxdate, -12 * 2)
 17  order by t.id, t.efdate desc;

        ID EFDATE
---------- ----------
         1 2020-09-30
         1 2019-09-30
         1 2018-09-30
         2 2019-03-31
         2 2018-03-31
         2 2017-03-31

6 rows selected.

SQL>

这应该也有效。所有条件都在 WHERE 子句中。它采用每个组 ID 的最大日期并对每条记录进行减法,然后根据需要获得结果。

select * from tbl A
where (select max(B.effectivedate) from tbl B where A.id = B.id) - A.effectivedate < 740
order by A.id asc, A.effectivedate desc;