Bạn chỉ phải sử dụng một phép nối Descartes duy nhất để giải quyết vấn đề của bạn, không giống như các giải pháp khác, sử dụng nhiều phép toán. Tôi giả sử thời gian được lưu trữ dưới dạng VARCHAR2. Nếu nó được lưu trữ dưới dạng ngày tháng thì bạn có thể xóa các hàm TO_DATE. Nếu nó được lưu trữ dưới dạng ngày tháng (tôi thực sự khuyên bạn điều này), bạn sẽ phải xóa các phần ngày tháng
Tôi đã nói hơi dài dòng nên rõ ràng chuyện gì đang xảy ra.
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
Về cơ bản, điều này tính ra sự khác biệt tuyệt đối giữa mọi thời điểm trong T1 và T2, sau đó chọn sự khác biệt nhỏ nhất theo T2 ID
; trả lại dữ liệu từ T1.
Đây là định dạng SQL Fiddle .
Định dạng kém đẹp hơn (nhưng ngắn hơn) là:
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