在sql server中获取与给定日期时间最接近的前一个或将来的日期时间

时间:2017-08-31 12:20:00

标签: sql sql-server sql-server-2008

我正在尝试将最接近的轮询日期时间发送到OrderSubmittedtime,其中最接近的轮询日期时间可以是日期时间前一个或将来的日期(+或 - ),与OrderSubmittedtime相比,只要日期时间足够接近。

以下是此示例:

create table Rosters
(
OrderID int,
PollingTime datetime 
,OrdersubmittedTime datetime
)    

 insert into Rosters values (1,'2017-08-07 11:30:00.000','2017-08-07 04:12:51.000')
 insert into Rosters values (1,'2017-08-07 12:13:34.000','2017-08-07 04:12:51.000')
 insert into Rosters values (1,'2017-08-07 03:30:00.000','2017-08-07 04:12:51.000')
 insert into Rosters values (1,'2017-08-08 00:30:00.000','2017-08-07 04:12:51.000')
 insert into Rosters values (2,'2017-08-05 10:30:00.000','2017-08-07 04:12:51.000')
 insert into Rosters values (2,'2017-08-06 11:30:00.000','2017-08-07 04:12:51.000')
 insert into Rosters values (2,'2017-08-08 00:30:00.000','2017-08-07 04:12:51.000')

select * from Rosters

预期结果集是:      对于OrderID = 1,最接近的投票时间将为'2017-08-07 03:30:00.000' 对于OrderID = 2,最接近的投票时间为'2017-08-06 11:30:00.000'

我目前可以写下面的查询,但这不正确:

 select PollingTime
 ,OrdersubmittedTime
 ,OrderID
, abs(DATEDIFF(MINUTE,OrdersubmittedTime,PollingTime)) as ClosestPollingTime
 from Rosters

请帮助我,谢谢。

1 个答案:

答案 0 :(得分:1)

您可以使用OUTER APPLY加入同一个表中的子查询,并使用ClosestPollingTime这样的最接近的值(根据{{3}修改为过滤秒而不是分钟来自comment

CREATE TABLE #Rosters
(
    OrderID INT,
    PollingTime DATETIME,
    OrdersubmittedTime DATETIME
);

INSERT INTO #Rosters
VALUES
(1, '2017-08-07 11:30:00.000', '2017-08-07 04:12:51.000'),
(1, '2017-08-07 12:13:34.000', '2017-08-07 04:12:51.000'),
(1, '2017-08-07 03:30:00.000', '2017-08-07 04:12:51.000'),
(1, '2017-08-08 00:30:00.000', '2017-08-07 04:12:51.000'),
(2, '2017-08-05 10:30:00.000', '2017-08-07 04:12:51.000'),
(2, '2017-08-06 11:30:00.000', '2017-08-07 04:12:51.000'),
(2, '2017-08-08 00:30:00.000', '2017-08-07 04:12:51.000');


SELECT r.OrdersubmittedTime,
       r.OrderID,
       t.ClosestPollingTime
FROM #Rosters AS r
    OUTER APPLY
     (
         SELECT TOP 1
             r2.OrderID,
             r2.PollingTime as ClosestPollingTime
         FROM #Rosters AS r2
         WHERE r2.OrderID = r.OrderID
         ORDER BY ABS(DATEDIFF(SECOND, r2.OrdersubmittedTime, r2.PollingTime))
     ) t
GROUP BY r.OrdersubmittedTime,
         r.OrderID,
         t.ClosestPollingTime;

DROP TABLE #Rosters;

产地:

OrdersubmittedTime       OrderID     ClosestPollingTime
2017-08-07 04:12:51.000  1           2017-08-07 03:30:00.000
2017-08-07 04:12:51.000  2           2017-08-06 11:30:00.000