Vous n'avez qu'à utiliser une seule jointure cartésienne pour résoudre votre problème contrairement aux autres solutions, qui en utilisent plusieurs. Je suppose que le temps est stocké en tant que VARCHAR2. S'il est stocké sous forme de date, vous pouvez supprimer les fonctions TO_DATE. S'il est stocké sous forme de date (je le recommande vivement), vous devrez supprimer les parties de date
Je l'ai rendu légèrement verbeux pour que ce soit évident ce qui se passe.
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
Fondamentalement, cela calcule la différence absolue entre chaque fois dans T1 et T2, puis sélectionne la plus petite différence par T2 ID
; renvoyant les données de T1.
Le voici au format SQL Fiddle .
Le format le moins joli (mais plus court) est :
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