I need help with one task I'm trying to finish. I need to join my data into the smallest possible date ranges and retrieve MIN(P_MIN) and SUM(P_MAX) over objects (in column 'name') under one id.
|ID |NAME |DATE_FROM |DATE_TO |P_MAX|P_MIN|
|---|--------|----------|----------|-----|-----|
|1 |OBJECT 1|10/11/2021|10/10/2022|150 |20 |
|1 |OBJECT 1|10/10/2022|02/02/2023|200 |40 |
|1 |OBJECT 1|02/02/2023|18/06/2027|100 |70 |
|1 |OBJECT 2|10/11/2021|01/05/2022|300 |60 |
|1 |OBJECT 2|01/05/2022|01/12/2022|50 |40 |
|1 |OBJECT 2|01/12/2022|18/06/2027|350 |40 |
For above I'd like to obtain
|ID |DATE_FROM |DATE_TO |SUM_P_MAX|P_MIN|
|---|----------|----------|---------|-----|
|1 |10/11/2021|01/05/2022|150+300 |20 |
|1 |01/05/2022|10/10/2022|50+150 |20 |
|1 |10/10/2022|01/12/2022|200+50 |40 |
|1 |01/12/2022|02/02/2023|350+200 |40 |
|1 |02/02/2023|18/06/2027|100+350 |40 |
"Tips"
- MIN(date_from) and MAX(date_to) is always the same per object (column 'name').
- MAX(date_to) can be NULL (that means object lasts to "infinity").
- Per one object date_from is always the same as previous date_to.
- There could be more than 2 objects under one id
- So for MIN(date_from) I need to find MIN(date_to) and then move to next line (so find next min(date_from/to)) and so on. The issue might be that there are two MIN(date_from) and MAX(date_to)
I was trying to resolve it using MATCH_RECOGNIZE but I couldn't get expected results. I'm fixed with MATCH_RECOGNIZE but maybe there is a better way to resolve this?
Can anyone help?
Data:
CREATE TABLE my_table (id number
,name varchar2(100)
,date_from date
,date_to date
,p_max number
,p_min number);
INSERT INTO my_table VALUES (1, 'OBJECT 1', TO_DATE('10/11/2021', 'DD/MM/YYYY'), TO_DATE('10/10/2022', 'DD/MM/YYYY'), 150, 20);
INSERT INTO my_table VALUES (1, 'OBJECT 1', TO_DATE('10/10/2022', 'DD/MM/YYYY'), TO_DATE('02/02/2023', 'DD/MM/YYYY'), 200, 40);
INSERT INTO my_table VALUES (1, 'OBJECT 1', TO_DATE('02/02/2023', 'DD/MM/YYYY'), TO_DATE('18/06/2027', 'DD/MM/YYYY'), 100, 70);
INSERT INTO my_table VALUES (1, 'OBJECT 2', TO_DATE('10/11/2021', 'DD/MM/YYYY'), TO_DATE('01/05/2022', 'DD/MM/YYYY'), 300, 60);
INSERT INTO my_table VALUES (1, 'OBJECT 2', TO_DATE('01/05/2022', 'DD/MM/YYYY'), TO_DATE('01/12/2022', 'DD/MM/YYYY'), 50, 40);
INSERT INTO my_table VALUES (1, 'OBJECT 2', TO_DATE('01/12/2022', 'DD/MM/YYYY'), TO_DATE('18/06/2027', 'DD/MM/YYYY'), 350, 40);
You may use
modelclause to reference values of other rows and calculate such totals.The idea behind this solution is to calculate new end dates for each interval (as long as each interval has no gaps a new end date is a next start date). And then calculate total for intersection of this interval with all original intervals.