Devi solo utilizzare un unico join cartesiano per risolvere il tuo problema a differenza delle altre soluzioni, che ne utilizzano più. Presumo che il tempo sia memorizzato come VARCHAR2. Se è memorizzato come data, è possibile rimuovere le funzioni TO_DATE. Se è memorizzato come data (lo consiglio vivamente), dovrai rimuovere le parti della data
L'ho reso leggermente dettagliato, quindi è ovvio cosa sta succedendo.
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
Fondamentalmente, questo calcola la differenza assoluta tra ogni volta in T1 e T2, quindi seleziona la differenza più piccola per T2 ID
; restituire i dati da T1.
Eccolo in formato SQL Fiddle .
Il formato meno carino (ma più breve) è:
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