在Oracle SQL中选择最新结果

时间:2018-03-12 20:18:33

标签: sql oracle join plsql

我正在尝试根据两个日期选择最近一行(利率IntRate)。最优先的日期是EffDate,而第二个日期是LastMaintenanceEffDate具有IntRate生效的日期。所以格式有这样的,MM/DD/YYYYLastMaintenance列最后一次以SYSDATE

的格式更改了行

例如,如果我在同一天内更改IntRate,我会在历史记录表中获得两行。两者都具有相同的EffDate但不同的LastMaintenance日期。

目前,我正在尝试根据给定帐户的IntRate历史记录表格选择最新的IntRate。所以我想根据日期选择最新的IntRate。与该日期最接近的IntRate是我想要使用的。

问题是,当IntRate相同但EffDate不同时,我无法弄清楚如何选择最新的DateLastMaintenance

在下图中,如何选择价值为IntRate的{​​{1}}?我想要那个,因为即使null相同,EffDate字段对DateLastMaintenance值也更新。

Example

我有类似的东西来获取给定AcctNbr的最新null以及我想要最新值的日期。

EffDate

这将给我一个SELECT EffDate FROM (SELECT * FROM AcctRateHist X WHERE X.AcctNbr = A.AcctNbr -- R.Acctnbr AND X.EffDate <= TO_DATE('09-26-2017', 'MM-DD-YYYY') -- The date to get the most recent value for ORDER BY X.EffDate DESC, X.DateLastMaint DESC) WHERE ROWNUM = 1; 的9月14日,但当我把它连接到一个外部查询时,我得到的所有行的EffDate为9/14/2017,所以我现在需要查看EffDate列。

我尝试选择DateLastMaintenance,但得到ROWNUM = 1为0.0375,而不是IntRate值为1(null,我没有得到为什么它拿起那个..)。

ROWNUM = 2

2 个答案:

答案 0 :(得分:1)

我认为你想使用元组:

(X.EffDate, X.DateLastMaint) =
    (SELECT EffDate, DateLastMaint -- This gets the EffDate of 9/14/2017
     FROM (SELECT *
           FROM AcctRateHist X
           WHERE X.AcctNbr = A.AcctNbr AND
                 X.EffDate <= DATE '2017-09-26' -- The date to get the most recent value for
           ORDER BY X.EffDate DESC, X.DateLastMaint DESC)
     WHERE ROWNUM = 1
    )

答案 1 :(得分:1)

窗口函数非常适合此任务。这是一个DENSE_RANK示例。

create table acctratehist ( acctnbr int, intrate number (9,3), effdate date, datelastmaint timestamp);

insert into acctratehist values (89, 2.125, DATE '2018-03-11', TIMESTAMP '2018-03-11 11:00:00');
insert into acctratehist values (89, 2.375, DATE '2018-03-11', TIMESTAMP '2018-03-11 15:00:00');
insert into acctratehist values (89, 2.825, DATE '2018-03-12', TIMESTAMP '2018-03-12 13:00:00');
insert into acctratehist values (52, 2.000, DATE '2018-03-11', TIMESTAMP '2018-03-11 15:00:00');
insert into acctratehist values (52, 2.333, DATE '2018-03-12', TIMESTAMP '2018-03-12 13:00:00');

select t.acctnbr, t.effdate, t.intrate
from (
  select acctnbr, intrate, effdate, dense_rank() over (partition by acctnbr, effdate order by datelastmaint desc) as dlmrank
  from acctratehist
) t
where t.dlmrank = 1
order by t.acctnbr, t.effdate

SQLFiddle