I've a transaction table of purchased and returned items, and I want to match a return transaction with the transaction where that corresponding item was purchased. (Here I used the same item ID and amount in all records for simplicity)
trans_ID | date | item_ID | amt | type |
---|---|---|---|---|
1 | 2022-01-09 | 100 | 5000 | purchase |
2 | 2022-01-07 | 100 | 5000 | return |
3 | 2022-01-06 | 100 | 5000 | purchase |
4 | 2022-01-05 | 100 | 5000 | purchase |
5 | 2022-01-04 | 100 | 5000 | return |
6 | 2022-01-03 | 100 | 5000 | return |
7 | 2022-01-03 | 100 | 5000 | purchase |
8 | 2022-01-02 | 100 | 5000 | purchase |
9 | 2022-01-01 | 100 | 5000 | return |
Matching conditions are:
- The return date must be greater than or equal the purchase date
- The return and purchase transactions must relate to the same item's ID and same transaction amount
- For each return, there must be only 1 purchase matched to it (In case there are many related purchases, choose one with the most recent purchase date. But if the most recent purchase was already used for mapping with another return, choose the second-most recent purchase instead, and so on.)
- From 3), that means each purchase must be matched with only 1 return as well.
The result should look like this.
trans_ID | date | trans_ID_matched | date_matched |
---|---|---|---|
2 | 2022-01-07 | 3 | 2022-01-06 |
5 | 2022-01-04 | 7 | 2022-01-03 |
6 | 2022-01-03 | 8 | 2022-01-02 |
This is what I've tried.
with temp as (
select a.trans_ID, a.date
, b.trans_ID as trans_ID_matched
, b.date as date_matched
, row_number() over (partition by a.trans_ID, a.date order by b.date desc) as rn1
from
(
select *
from transaction_table
where type = 'return'
) a
inner join
(
select *
from transaction_table
where type = 'purchase'
) b
on a.item_ID = b.item_ID and a.amount = b.amount and a.date >= b.date
)
select * from temp where rn = 1
But what I got is
trans_ID | date | trans_ID_matched | date_matched |
---|---|---|---|
2 | 2022-01-07 | 3 | 2022-01-06 |
5 | 2022-01-04 | 7 | 2022-01-03 |
6 | 2022-01-03 | 7 | 2022-01-03 |
Here, the trans ID 7 shouldn't be used again in the last row as it has been already matched with trans ID 5 in the row 2. So is there any way to match trans ID 6 with 8 (or any way to tell SQL not to use the already-used one like the purchase 7) ?