From Oracle 12, you can use MATCH_RECOGNIZE
with LEAST
and GREATEST
:
SELECT "From", "To", "Start", "End"
FROM (
SELECT t.*,
LEAST("From", "To") AS lst,
GREATEST("From", "To") AS gst
FROM table_name t
)
MATCH_RECOGNIZE(
PARTITION BY lst, gst
ORDER BY "Start", "End"
ALL ROWS PER MATCH
PATTERN ( missed_call callback )
DEFINE
missed_call AS "Start" = "End",
callback AS PREV("From") = "To"
AND PREV("To") = "From"
AND "Start" < "End"
);
Which, for the sample data:
CREATE TABLE table_name ("From", "To", "Start", "End") AS
SELECT '9901234567', '8854320145', '10:00', '10:00' FROM DUAL UNION ALL
SELECT '9435678911', '7657894335', '10:30', '10:33' FROM DUAL UNION ALL
SELECT '8764091245', '9765487678', '09:45', '09:47' FROM DUAL UNION ALL
SELECT '8854320145', '9901234567', '10:05', '10:07' FROM DUAL UNION ALL
SELECT '7609123987', '8854320145', '11:13', '11:13' FROM DUAL UNION ALL
SELECT '6501928465', '7609123987', '08:09', '08:13' FROM DUAL UNION ALL
SELECT '1234567890', '1234567890', '09:00', '09:01' FROM DUAL UNION ALL
SELECT '1234567890', '1234567890', '09:05', '09:06' FROM DUAL UNION ALL
SELECT '1111111111', '2222222222', '10:00', '10:01' FROM DUAL UNION ALL
SELECT '2222222222', '1111111111', '10:05', '10:06' FROM DUAL;
Outputs:
From |
To |
Start |
End |
9901234567 |
8854320145 |
10:00 |
10:00 |
8854320145 |
9901234567 |
10:05 |
10:07 |
fiddle