Du behöver bara använda en enda kartesisk koppling för att lösa ditt problem till skillnad från de andra lösningarna, som använder flera. Jag antar att tiden lagras som en VARCHAR2. Om det lagras som ett datum kan du ta bort TO_DATE-funktionerna. Om det lagras som ett datum (jag rekommenderar starkt detta), måste du ta bort dadelportionerna
Jag har gjort det lite mångsidigt så det är uppenbart vad som händer.
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
I grund och botten räknar detta ut den absoluta skillnaden mellan varje gång i T1 och T2 och väljer sedan den minsta skillnaden med T2 ID
; returnerar data från T1.
Här är den i SQL Fiddle-format .
Det mindre snygga (men kortare) formatet är:
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