2012-02-01 69 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