Aby rozwiązać problem, musisz użyć tylko jednego sprzężenia kartezjańskiego, w przeciwieństwie do innych rozwiązań, które używają wielu. Zakładam, że czas jest przechowywany jako VARCHAR2. Jeśli jest przechowywany jako data, możesz usunąć funkcje TO_DATE. Jeśli jest przechowywany jako data (bardzo polecam), będziesz musiał usunąć porcje daty
Zrobiłem to nieco gadatliwe, więc widać, co się dzieje.
select *
from ( select id, tm
, rank() over ( partition by t2id order by difference asc ) as rnk
from ( select t1.*, t2.id as t2id
, abs( to_date(t1.tm, 'hh24:mi:ss')
- to_date(t2.tm, 'hh24:mi:ss')) as difference
from t1
cross join t2
) a
)
where rnk = 1
Zasadniczo oblicza to bezwzględną różnicę między każdym czasem w T1 i T2, a następnie wybiera najmniejszą różnicę według T2 ID
; zwracanie danych z T1.
Tutaj jest w format SQL Fiddle .
Mniej ładny (ale krótszy) format to:
select *
from ( select t1.*
, rank() over ( partition by t2.id
order by abs(to_date(t1.tm, 'hh24:mi:ss')
- to_date(t2.tm, 'hh24:mi:ss'))
) as rnk
from t1
cross join t2
) a
where rnk = 1