根据Oracle中的条件查找上一个记录的最大值

时间:2018-06-19 21:17:52

标签: sql oracle plsql

我需要找到上一个记录的开始日期和结束日期小于或等于当前开始日期记录的上一个交易结束日期的最大值。

第一笔记录(ID:101)将为空,因为这是第一笔交易。我尝试使用滞后函数,但对如何将当前记录的开始日期与所有先前的开始日期和结束日期进行比较感到震惊。

Transaction ID Transaction Start Date Transaction End Date Last Transaction Date
-------------- ---------------------- -------------------- ---------------------
           101 07/07/2015             07/09/2015           null
           102 10/06/2015 10/08/2015  07/09/2015
           103 10/08/2015 10/08/2015  10/08/2015
           104 10/08/2015 10/08/2015  10/08/2015
           105 10/27/2015 10/28/2015  10/08/2015
           106 10/27/2015 10/28/2015  10/08/2015
           107 10/27/2015 10/29/2015  10/08/2015
           108 10/27/2015 10/30/2015  10/08/2015
           109 10/29/2015 10/29/2015  10/29/2015
           110 11/10/2015 11/12/2015  10/30/2015

3 个答案:

答案 0 :(得分:1)

一种方法是相关子查询:

select t.*,
       (select max(t2.enddate)
        from t t2
        where t2.id < t.id and
              t2.enddate <= t.startdate
       )
from t;

这是假设开始日期在结束日期或之前,因此开始日期的条件是多余的。

这还假定“先前记录”基于id。如果您只是想按时间先后顺序进行记录,则可以删除该条件。

答案 1 :(得分:0)

自从您将数据集编辑了大约5次以上以来,我不得不一遍又一遍地对其进行测试。请考虑别人的时间和精力来帮助您。 。

无论如何,这是考虑表名称为t且列为tid, ts, te的解决方案,它们是事务ID,开始日期和结束日期的缩写:

select 
  t.tid as "Transaction ID", 
  t.ts as "Transaction Start Date",
  t.te as "Transaction End Date",
  max(t2.te) as "Last Transaction Date"
from t
left join t t2 on
  t.ts >= t2.ts -- might not be needed, if end date > start date always (should be)
  and t.ts >= t2.te
  and t.tid > t2.tid
group by t.tid, t.ts, t.te
order by t.tid

结果:

 Transaction ID | Transaction Start Date | Transaction End Date | Last Transaction Date
----------------+------------------------+----------------------+-----------------------
            101 | 2015-07-07             | 2015-07-09           | NULL
            102 | 2015-10-06             | 2015-10-08           | 2015-07-09
            103 | 2015-10-08             | 2015-10-08           | 2015-10-08
            104 | 2015-10-08             | 2015-10-08           | 2015-10-08
            105 | 2015-10-27             | 2015-10-28           | 2015-10-08
            106 | 2015-10-27             | 2015-10-28           | 2015-10-08
            107 | 2015-10-27             | 2015-10-29           | 2015-10-08
            108 | 2015-10-27             | 2015-10-30           | 2015-10-08
            109 | 2015-10-29             | 2015-10-29           | 2015-10-29
            110 | 2015-11-10             | 2015-11-12           | 2015-10-30

您不能使用lag()分析函数,因为它仅返回一行的值(如果没有另外指定,则返回上一行)。在这里,您需要JOIN并进行日期比较,并确保仅从以前的交易t.tid > t2.tid中获取数据。然后将max(t2.te)用于匹配的记录。

答案 2 :(得分:0)

如果我正确理解您的要求,则可以通过使用select子查询来实现。让我知道您是否需要其他更改,我可以为您进行编译。

SELECT t.id,
       t.startDt,
       t.endDt,
  (SELECT max(t1.endDt)
   FROM transactions t1
   WHERE t1.endDt <= t.startDt
     AND t1.id < t.id) AS lastTxDt
FROM transactions t;