【问题标题】:Selecting most recent result in Oracle SQL在 Oracle SQL 中选择最近的结果
【发布时间】:2018-08-20 23:26:49
【问题描述】:

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

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

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

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

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

我有这样的东西来获取给定 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;

这将为我提供 2017 年 9 月 14 日的 EffDate,但是当我将其连接到外部查询时,我会得到所有行的 EffDate 为 2017 年 9 月 14 日,所以我需要查看现在在DateLastMaintenance 列。

我试图选择ROWNUM = 1,但它得到的是 0.0375 的 IntRate 而不是 null 值一(ROWNUM = 2,我不明白为什么它会选择那个.. )。

SELECT R.AcctNbr, X.EffDate, X.IntRate, X.InactiveDate, X.DateLastMaint
FROM AcctRateHist X, Rpt_Sort_Process R
WHERE X.AcctNbr = R.AcctNbr -- Just some stuff thats needed to get the AcctNbr: Ignore
AND R.QueNbr = somenum -- Just some stuff thats needed to get the AcctNbr: Ignore
AND R.ApplNbr = somenum -- Just some stuff thats needed to get the AcctNbr: Ignore
AND R.QueSubNbr = somenum -- Just some stuff thats needed to get the AcctNbr: Ignore
AND X.EffDate = (SELECT EffDate -- This gets the EffDate of 9/14/2017
                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)
AND ROWNUM = 1 -- This SHOULD return the IntRate of null, but doesn't
ORDER BY X.EffDate DESC, X.Datelastmaint DESC;

【问题讨论】:

  • 你能简化一下这个问题吗?这么长的文章很难读。

标签: sql oracle join plsql


【解决方案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
    )

【讨论】:

    【解决方案2】:

    窗口函数非常适合此任务。这是一个 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

    【讨论】:

      猜你喜欢
      • 2018-06-12
      • 2012-07-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-16
      • 1970-01-01
      • 2020-05-07
      相关资源
      最近更新 更多