[英]T-SQL Overlapping time range parameter in stored procedure
我想搜索發生在一天中特定時間以及日期/時間范圍之間的記錄。
例:
我的桌子:
ID | EmpID | AuthorizationTime
-------------------------------
1 | 21455 | '23/01/2012 12:44'
2 | 22311 | '23/01/2012 18:15'
3 | 21455 | '23/01/2012 23:04'
4 | 10222 | '24/01/2012 03:31'
5 | 21456 | '24/01/2012 09:00'
6 | 53271 | '25/01/2012 12:15'
7 | 10222 | '26/01/2012 18:30'
8 | 76221 | '27/01/2012 09:00'
SP輸入參數樣本:
@from: 22/01/2012 08:00
@to: 24/01/2012 23:00
@fromtime: 18:30
@totime: 08:00
預期產量:
EntryID EmployeeID AuthorisationTime
3 21455 '23/01/2012 23:04'
4 10222 '24/01/2012 03:31'
我已經在SP中嘗試了以下select語句:
...
Select @wAuthorizationTime=' AuthorizationTime between ''' + CONVERT(nvarchar(30), @from )+ ''' and ''' + convert(nvarchar(50),@to )+ ''' '
Select @Where = @wAuthorizationTime; Declare @wHours nvarchar(1000)='';
if (ISNULL(@fromtime,'')<>'' and ISNULL(@ToTime,'')<> '') begin Select @wHours= ' (Cast(AuthorizationTime as time) between ''' + @fromTime + ''' and '''+ @ToTime +''')'
end if (@wHours <> '') Select @Where=@Where + ' and ' + @wHours
...
該語句的問題在於,如果結束時間比開始時間短(例如23:00至03:00),則我沒有任何結果。
如果我使用不重疊的時間范圍(例如18:00至23:59),它確實可以工作。
我需要做些什么才能獲得以上結果?
添加檢查以查看@fromtime > @totime
。 如果是這種情況,請像下面這樣比較AuthorizationTime的TIME廣播值:
(cast(AuthorizationTime as time) between '00:00:00' and @totime) or
(cast(AuthorizationTime as time) between @fromtime and '23:59:59.999')
這應該給您您想要的:
select *
from Times
where AuthorizationTime >= @from
and AuthorizationTime <= @to
and (
(@fromtime > @totime and ((cast(AuthorizationTime as time) between '00:00:00' and @totime) or
(cast(AuthorizationTime as time) between @fromtime and '23:59:59.999')
)
) or
(@fromtime <= @totime and cast(AuthorizationTime as time) between @fromtime and @totime)
)
-在SELECT語句之前執行復雜的工作
declare @from DateTime,
@to DateTime,
@fromTime int,
@totime int
-- sample data:
set @from = convert(datetime, '22/01/2012 08:00', 103)
set @to = convert(varchar, '24/01/2012 23:00', 103)
-- first truncte the date
set @from = convert(datetime, convert(varchar, @from, 103), 103)
set @to = convert(datetime, convert(varchar, @to, 103), 103)
-- then build the time as an int: Hour * 100 + Minute
set @fromTime = 1830
set @toTime = 800 -- note this is an int
-- Then use this to do the where clause:
select *
from myTable
where AuthorisationTime between @from and @to
and (DATEPART(HOUR, AuthorizationTime) * 100 + DATEPART(MINUTE, AuthorizationTime)
>= @fromTime OR
DATEPART(HOUR, AuthorizationTime) * 100 + DATEPART(MINUTE, AuthorizationTime)
<= @toTime)
我認為這很容易遵循,測試,並且更有可能利用索引。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.