2016-09-26 84 views
1

我想比較時間與時間範圍,如果該特定時間在於 - 在該時間範圍內,則它應該返回記錄。Sql Server - 僅比較24小時格式的時間?

例如,表「A」有:

+-----------+------+-------------+-----------+ 
| User_Code | Name | Shift_Start | Shift_End | 
+-----------+------+-------------+-----------+ 
|   1 | ABC | 04:01:00 | 11:00:00 | 
|   2 | DEF | 11:01:00 | 20:00:00 | 
|   3 | XYZ | 20:01:00 | 04:00:00 | 
+-----------+------+-------------+-----------+ 

現在我要檢查其轉變是它在這個特定日期時間:2016-09-26 02:51:59。 SQL查詢應返回User_Code = 3Shift_StartShift_End的類型爲time

我試圖轉換2016-09-26 02:51:59時間,然後shift_startshift_end使用between和使用logical operator,但我無法得到期望的結果與比較。

這讓我感到莫名其妙。自從我嘗試提出解決方案以來,已經過去了一個小時,但我無法這樣做。試圖用Google搜索,但沒有得到任何東西。任何幫助將不勝感激。使用SQL Server從另一個角度2012

+1

如果你只想處理'TIME'而不是'DATETIME',它可能使您的生活更輕鬆分割您'20 :01:00 - 04:00:00 XYZ'分爲兩個範圍:'00:00:00 - 04:00:00 XYZ'和'20:01:00 - 23:59:59 XYZ' – paul

+0

@paul,是的,但我並不想改變數據庫結構,但我同意這會讓事情變得更容易。 – NewbieProgrammer

回答

3

您需要更復雜的where條件,因爲換檔時間可以按任一順序。

所以:

where ((shift_start < shift_end) and 
     cast(@datetime as time) between shift_start and shift_end) 
    ) or 
     ((shift_start > shift_end) and 
     cast(@datetime as time) not between shift_end and shift_start) 
    ) 
+0

謝謝兄弟。我沒有意識到我可以做'不在'之間。 – NewbieProgrammer

+0

@戈登Linoff,我知道這是回答。但是當我嘗試通過'@datetime ='2016-09-24 17:51:59''時,它給了2行(2和3),而不是一個。 – user3583912

+0

@ user3583912。 。 。 'between'和'not between'之間的運算符首先需要較低的值。 –

0

方法和搜索條件的日期部分添加到換擋開始時間和結束時間:

注意case語句,這種處理情況移位結束越過午夜。

DECLARE @dateTime DATETIME = '2016-09-26 02:51:59' 
-- Remove the time portion of above 
DECLARE @datePortion DATETIME = DATEADD(dd, 0, DATEDIFF(dd, 0, @dateTime)) 

SELECT * FROM TableA 
    WHERE @dateTime BETWEEN @datePortion + cast(Shift_Start as datetime) 
        AND CASE WHEN ShiftEnd < ShiftStart 
          THEN DATEADD(day, 1, @datePortion) 
          ELSE @datePortion 
         END + cast(Shift_End as datetime) 
+0

不幸的是,這並沒有產生預期的結果。 – NewbieProgrammer

1
declare @t table(
    User_Code int, 
    Name varchar(20), 
    Shift_Start time, 
    Shift_End time 
    ); 
insert @t(User_Code,Name,Shift_Start,Shift_End) 
values 
(1,'ABC','04:01:00','11:00:00') 
,(2,'DEF','11:01:00','20:00:00') 
,(3,'XYZ','20:01:00','04:00:00'); 

嘗試

declare @d datetime = '2016-09-26 02:51:59'; 

select * 
from @t 
cross apply (-- intermediate vars: rounded param 
     select dt = cast(cast(@d as date) as datetime) 
      ) r 
where @d between dateadd(d, case when Shift_Start<Shift_End then 0 else -1 end, dt) + cast(Shift_start as datetime) 
     and dt+cast(Shift_end as datetime);