Solo tiene que usar una sola unión cartesiana para resolver su problema, a diferencia de las otras soluciones, que usan múltiples. Supongo que el tiempo se almacena como VARCHAR2. Si se almacena como una fecha, puede eliminar las funciones TO_DATE. Si se almacena como una fecha (lo recomendaría encarecidamente), deberá eliminar las porciones de fecha
Lo he hecho un poco detallado para que sea obvio lo que está pasando.
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
Básicamente, esto calcula la diferencia absoluta entre cada tiempo en T1 y T2 y luego selecciona la diferencia más pequeña por T2 ID
; devolviendo los datos de T1.
Aquí está en formato SQL Fiddle .
El formato menos bonito (pero más corto) es:
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