簡體   English   中英

存儲過程中的T-SQL重疊時間范圍參數

[英]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)
    )

SQL小提琴

-在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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM