如何在Oracle sql中获取最接近的日期

fen*_*sss 9 sql oracle date-arithmetic

例如,我有2个时间表:T1

id time
1 18:12:02
2 18:46:57
3 17:49:44
4 12:19:24
5 11:00:01
6 17:12:45
Run Code Online (Sandbox Code Playgroud)

和T2

id time
1 18:13:02
2 17:46:57
Run Code Online (Sandbox Code Playgroud)

我需要从T1获得与T2时间最接近的时间.这些表之间没有关系.它应该是这样的:

select T1.calldatetime
from T1, T2 
where T1.calldatetime between 
T2.calldatetime-(
    select MIN(ABS(T2.calldatetime-T1.calldatetime))
    from T2, T1)
and
T2.calldatetime+(
    select MIN(ABS(T2.calldatetime-T1.calldatetime))
    from T2, T1)
Run Code Online (Sandbox Code Playgroud)

但我无法得到它.有什么建议?

Ben*_*Ben 8

与其他使用多个解决方案的解决方案不同,您只需使用单个笛卡尔连接来解决问题.我假设时间存储为VARCHAR2.如果它存储为日期,则可以删除TO_DATE函数.如果它存储为日期(我强烈推荐这个),你将不得不删除日期部分

我已经略显冗长,所以很明显发生了什么.

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
Run Code Online (Sandbox Code Playgroud)

基本上,这可以解决T1和T2中每次的绝对差异,然后选择T2的最小差值ID; 从T1返回数据.

这是SQL Fiddle格式.

不太漂亮(但更短)的格式是:

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
Run Code Online (Sandbox Code Playgroud)


mav*_*ato 5

我相信这是您正在寻找的查询:

CREATE TABLE t1(id INTEGER, time DATE);
CREATE TABLE t2(id INTEGER, time DATE);

INSERT INTO t1 VALUES (1, TO_DATE ('18:12:02', 'HH24:MI:SS'));
INSERT INTO t1 VALUES (2, TO_DATE ('18:46:57', 'HH24:MI:SS'));
INSERT INTO t1 VALUES (3, TO_DATE ('17:49:44', 'HH24:MI:SS'));
INSERT INTO t1 VALUES (4, TO_DATE ('12:19:24', 'HH24:MI:SS'));
INSERT INTO t1 VALUES (5, TO_DATE ('11:00:01', 'HH24:MI:SS'));
INSERT INTO t1 VALUES (6, TO_DATE ('17:12:45', 'HH24:MI:SS'));

INSERT INTO t2 VALUES (1, TO_DATE ('18:13:02', 'HH24:MI:SS'));
INSERT INTO t2 VALUES (2, TO_DATE ('17:46:57', 'HH24:MI:SS'));

SELECT t1.*, t2.*
  FROM t1, t2,
       (  SELECT t2.id, MIN (ABS (t2.time - t1.time)) diff
            FROM t1, t2
        GROUP BY t2.id) b
 WHERE ABS (t2.time - t1.time) = b.diff;
Run Code Online (Sandbox Code Playgroud)

确保时间列具有相同的日期部分,因为否则 t2.time - t1.time 部分将无法工作。

编辑:感谢您的接受,但本下面的答案更好。它使用 Oracle 分析函数并且性能会更好。