Это может быть достигнуто с помощью простого соединения .Нет необходимости использовать какие-либо функции.
Попробуйте следующий код, если TIME_A и TIME_B непрерывны:
WITH tableA ( TIME_A, EVENT_A ) AS
(SELECT 1, 'a1' FROM DUAL UNION ALL
SELECT 2, 'a1' FROM DUAL UNION ALL
SELECT 3, 'a1' FROM DUAL UNION ALL
SELECT 4, 'a0' FROM DUAL UNION ALL
SELECT 5, 'a2' FROM DUAL UNION ALL
SELECT 6, 'a2' FROM DUAL UNION ALL
SELECT 7, 'a3' FROM DUAL UNION ALL
SELECT 8, 'a0' FROM DUAL),
tableB ( TIME_B, EVENT_B ) AS
(SELECT 1, 'b1' FROM DUAL UNION ALL
SELECT 2, 'b2' FROM DUAL UNION ALL
SELECT 3, 'b3' FROM DUAL UNION ALL
SELECT 4, 'b4' FROM DUAL UNION ALL
SELECT 5, 'b5' FROM DUAL UNION ALL
SELECT 6, 'b5' FROM DUAL UNION ALL
SELECT 7, 'b6' FROM DUAL UNION ALL
SELECT 8, 'b7' FROM DUAL)
SELECT
TIME_A,
EVENT_A,
TIME_B,
EVENT_B
FROM
TABLEA A
JOIN TABLEB B ON ( EVENT_A = 'a0'
AND TIME_B BETWEEN TIME_A - 2 AND TIME_A )
ORDER BY
TIME_A,
TIME_B
Попробуйте следующий код, если TIME_A и TIME_B не непрерывны:
WITH tableA ( TIME_A, EVENT_A ) AS
(SELECT 1, 'a1' FROM DUAL UNION ALL
SELECT 2, 'a1' FROM DUAL UNION ALL
SELECT 3, 'a1' FROM DUAL UNION ALL
SELECT 4, 'a0' FROM DUAL UNION ALL
SELECT 5, 'a2' FROM DUAL UNION ALL
SELECT 6, 'a2' FROM DUAL UNION ALL
SELECT 7, 'a3' FROM DUAL UNION ALL
SELECT 8, 'a0' FROM DUAL),
tableB ( TIME_B, EVENT_B ) AS
(SELECT 1, 'b1' FROM DUAL UNION ALL
SELECT 2, 'b2' FROM DUAL UNION ALL
SELECT 3, 'b3' FROM DUAL UNION ALL
SELECT 4, 'b4' FROM DUAL UNION ALL
SELECT 5, 'b5' FROM DUAL UNION ALL
SELECT 6, 'b5' FROM DUAL UNION ALL
SELECT 7, 'b6' FROM DUAL UNION ALL
SELECT 8, 'b7' FROM DUAL)
SELECT
TIME_A,
EVENT_A,
TIME_B,
EVENT_B FROM
(SELECT
TIME_A,
EVENT_A,
TIME_B,
EVENT_B,
ROW_NUMBER() OVER (PARTITION BY TIME_A ORDER BY TIME_B DESC NULLS LAST) AS RN
FROM
TABLEA A
JOIN TABLEB B ON ( EVENT_A = 'a0'
AND TIME_B <= TIME_A ))
WHERE RN <= 3
ORDER BY
TIME_A,
TIME_B
Демо-версия DB Fiddle
Приветствия !!