T-SQL - 在同一语句中查询当前时间之前和之后的记录

时间:2012-02-01 22:54:03

标签: sql tsql datetime

对于你的T-SQL大师:

我有下表:

ID              Arrival
1       06:16:00
2       06:17:00
3               07:19:00
4       08:21:00
5       10:22:00
6       13:21:00
7       20:22:00

假设时间目前是08:00 AM,我想在记录之前和之后选择2条记录,最接近现在。结果应返回ID为2,3,4,5和6的记录。

获取ID = 4的记录之前和之后的记录是直截了当的,但到目前为止,我无法弄清楚如何将完整集作为同一查询的一部分返回。我有这两个选择语句:

SELECT TOP(2) * FROM Schedules 
where (datepart(hour, Arrival) - datepart(hour, getdate()))*60 + datepart(minute, Arrival) - datepart(minute, getdate())  < 0
order by (datepart(hour, Arrival) - datepart(hour, getdate()))*60 + datepart(minute, Arrival) - datepart(minute, getdate())

SELECT TOP(2) * FROM Schedules 
where (datepart(hour, Arrival) - datepart(hour, getdate()))*60 + datepart(minute, Arrival) - datepart(minute, getdate())  >= 0
order by (datepart(hour, Arrival) - datepart(hour, getdate()))*60 + datepart(minute, Arrival) - datepart(minute, getdate()) asc

返回前后的记录。我尝试在两个语句上使用union,但这需要删除第一个order by子句,这会使我的查询条件无效。

任何想法都会有所帮助,谢谢。

2 个答案:

答案 0 :(得分:1)

如果到达时间或之后,我们可以使用ROW_NUMBER进行分区,并按到达时间和输入时间之差的绝对值进行排序。

DECLARE @CurrentTime as  time 
SET @CurrentTime = '08:00 AM'

DECLARE @Schedules  table  (id int, arrival time)
INSERT INTO @Schedules
VALUES (1 , '06:16:00' ),
(2, '06:17:00' ),
(3, '07:19:00'),
(4, '08:21:00'),
(5, '10:22:00'),
(6, '13:21:00'),
(7, '20:22:00')

DECLARE @closestTime as time
SELECT TOP 1 @closestTime = arrival  FROM @Schedules ORDER BY ABS(DATEDIFF(mi, @CurrentTime ,arrival))

;WITH cte 
     AS (SELECT id, 
                arrival, 
                Row_number() OVER (PARTITION BY (CASE WHEN @closestTime > arrival THEN 1 
                                                      WHEN @closestTime < arrival THEN 2 END) 
                                   ORDER BY Abs(Datediff(mi, @closestTime, arrival))) rn 
         FROM   @Schedules) 
SELECT * 
FROM   cte 
WHERE  rn < 3 
        OR arrival = @closestTime 
ORDER  BY id

结果

id          arrival          rn
----------- ---------------- --------------------
2           06:17:00.0000000 2
3           07:19:00.0000000 1
4           08:21:00.0000000 1
5           10:22:00.0000000 1
6           13:21:00.0000000 2

请参阅此data.se query

的工作示例

答案 1 :(得分:0)

您可以尝试以下方法吗?我已经测试过,得到了你想要的结果

create table Arriavel (ID int, Arr_time time)

insert into Arriavel values (1, '06:16:00')
insert into Arriavel values (2, '06:17:00')
insert into Arriavel values (3, '07:19:00')
insert into Arriavel values (4, '08:21:00')
insert into Arriavel values (5, '10:22:00')
insert into Arriavel values (6, '13:21:00')
insert into Arriavel values (7, '20:22:00')


declare @cur_time time

set @cur_time = '08:00:00'

select max(arr_time) arr_time
from Arriavel
where arr_time < @cur_time

union all

select min(arr_time) arr_time
from Arriavel
where arr_time > @cur_time