2012-02-01 71 views
1

当前时间后,你的T-SQL大师: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语句:

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 

哪些返回前后的记录。我试图在两个语句上使用联合,但这需要删除第一个子句,这会使我的查询条件失效。

任何想法将有所帮助,谢谢。

回答

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

+0

哇,这个答案。永远不会想到这个给定的时间限制。再次感谢您的链接。 – 2012-02-02 00:35:01

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 
+0

“结果应该返回ID为2,3,4,5和6的记录”,你的SQL只返回3和4的时间 – 2012-02-01 23:31:55