Reputation: 3
I need to find the max of Previous Transaction End Date where Previous record's Start and End Dates are less than or equal to the current Start Date records.
The first Record (ID: 101) will be null as this is the first transaction. I have tried using Lag function, but struck on how to compare the current record Start Date with all the Previous Start and End Dates.
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
Upvotes: 0
Views: 240
Reputation: 4874
If I understand your requirement correctly, you can achieve this by using select subquery. Let me know if you need additional changes, and I can compile that for you.
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;
Upvotes: 0
Reputation: 1269445
One method is a correlated subquery:
select t.*,
(select max(t2.enddate)
from t t2
where t2.id < t.id and
t2.enddate <= t.startdate
)
from t;
This assumes that the start date is on or before the end date, so a condition on start date is redundant.
This also assumes that "previous records" is based on the id
. You can remove that condition, if you just mean any records that occur before chronologically.
Upvotes: 1
Reputation: 17137
Since you edited your data set for like 5 times or more I had to test it over and over. Please consider other's people time and effort devoted to help you . . .
Anyways, here's the solution considering table name is t
and columns are tid, ts, te
which are short for transaction id, start and end dates:
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
Result:
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
You couldn't use lag()
analytic function because it returns value for only one row (previous, if not specified otherwise). This is where you need JOIN
with your comparison on dates and ensuring that you only take data from previous transactions t.tid > t2.tid
. Then take the max(t2.te)
for those records who were a match.
Upvotes: 0