Трябва да използвате само едно декартово съединение, за да решите проблема си, за разлика от другите решения, които използват множество. Предполагам, че времето се съхранява като VARCHAR2. Ако се съхранява като дата, можете да премахнете функциите TO_DATE. Ако се съхранява като дата (силно препоръчвам това), ще трябва да премахнете частите от датата
Направих го малко подробен, за да е очевидно какво се случва.
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
По принцип това изчислява абсолютната разлика между всяко време в T1 и T2, след което избира най-малката разлика по T2 ID
; връщане на данните от T1.
Ето го във формат на SQL Fiddle .
По-малко красивият (но по-кратък) формат е:
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