存储过程中的T-SQL重叠时间范围参数

时间:2014-05-26 09:46:14

标签: sql tsql stored-procedures sql-server-2008-r2

我想搜索在特定时间和日期/时间范围之间发生的记录。

示例:

我的表:

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),它确实有用。

我需要做些什么来获得上述结果?

3 个答案:

答案 0 :(得分:1)

添加一项检查以查看是否@fromtime > @totime。如果是这种情况,请比较AuthorizationTime的TIME-casted值,如下所示:

(cast(AuthorizationTime as time) between '00:00:00' and @totime) or
(cast(AuthorizationTime as time) between @fromtime and '23:59:59.999')

答案 1 :(得分:1)

这可以给你你想要的东西:

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 Fiddle

答案 2 :(得分:0)

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

我认为这很容易遵循,测试,并且更有可能使用索引。