在Oracle SQL中选择最新结果

在Oracle SQL中选择最新结果,sql,oracle,join,plsql,Sql,Oracle,Join,Plsql,我试图根据两个日期选择最近的行利率IntRate。最优先的日期是EffDate,第二个是LastMaintenance。EffDate具有IntRate生效的日期。所以格式是这样的,MM/DD/YYYY。LastMaintenance列包含行最后一次以SYSDATE格式更改的时间 例如,如果我在同一天内更改IntRate,我将在历史记录表中获得两行。两者的生效日期相同,但上次维护日期不同 现在,我正试图根据一个表来选择最近的IntRate,该表具有给定帐户的IntRate历史记录。因此,我想根据

我试图根据两个日期选择最近的行利率IntRate。最优先的日期是EffDate,第二个是LastMaintenance。EffDate具有IntRate生效的日期。所以格式是这样的,MM/DD/YYYY。LastMaintenance列包含行最后一次以SYSDATE格式更改的时间

例如,如果我在同一天内更改IntRate,我将在历史记录表中获得两行。两者的生效日期相同,但上次维护日期不同

现在,我正试图根据一个表来选择最近的IntRate,该表具有给定帐户的IntRate历史记录。因此,我想根据日期选择最近的IntRate。最接近该日期的IntRate是我想要使用的

问题是,当EffDate相同,但DateLastMaintenance不同时,我不知道如何选择最近的IntRate

在下图中,如何选择值为空的IntRate?我想要这个,因为即使EffDate是相同的,DateLastMaintenance字段对于空值来说还是较新的

我有类似这样的方法来获取给定AcctNbr的最新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;

我想您应该使用元组:

(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
    )

窗口功能非常适合此任务。这里有一个密集的例子

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

你能简化这个问题吗?这么长的一本很难读。
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