2016-06-13 3 views
1

Я ищу элегантный способ выбора записей, которые находятся между началом и временем окончания.SQL Server Между временем

У меня есть поле datetime, в котором хранятся дата и время записи. Я могу получить время на CAST(fieldname as time).

BETWEEN не работает, если вы ищете записи, которые произошли в период с 22:00 до 03:00

В идеале я хотел бы использовать CASE в пункте WHERE

CASE 
    WHEN @Start < @End THEN CAST(fieldname as time) BETWEEN @Start AND @END 
    ELSE (CAST(fieldname as time) > @Start OR CAST(fieldname as time) < @End) 
END 

Любые sugestions как я мог сделать это одним из элегантных способов.

Благодаря

+0

На самом деле 'BETWEEN' должно быть то, что вы используете ИМО. Если у вас также были даты, связанные с этими временами, то «BETWEEN» будет делать то, что вы хотите. –

+0

Нет, я должен получить все результаты, которые произошли между началом и временем окончания, независимо от даты –

+0

http://stackoverflow.com/questions/9840170/select-statement-filtering-by-time-of-day –

ответ

1

Элегантный способ:

SELECT *, CAST(datetimeFiled as time) 
FROM #Test 
WHERE 
    (@Start < @End AND (@Start < CAST(datetimeFiled as time) AND CAST(datetimeFiled as time) < @End)) 
    OR 
    (@Start > @End AND (@Start < CAST(datetimeFiled as time) OR CAST(datetimeFiled as time) < @End)) 

CASE WHEN путь:

SELECT *, CAST(datetimeFiled as time), 
    (CASE WHEN @Start < @End THEN 0 WHEN @Start > @End THEN 1 END) 
FROM #Test 
WHERE 1 = (
     CASE 
      WHEN @Start < @End THEN (SELECT 1 WHERE (@Start < CAST(datetimeFiled as time) AND CAST(datetimeFiled as time) < @End)) 
      WHEN @Start > @End THEN (SELECT 1 WHERE (@Start < CAST(datetimeFiled as time) OR CAST(datetimeFiled as time) < @End)) 
     END) 

Образец данных:

CREATE TABLE #Test(datetimeFiled DATETIME) 
INSERT INTO #Test 
VALUES 
('2016-06-13 13:11:00'), 
('2016-06-12 23:11:00'), 
('2016-06-12 23:00:00'), 
('2016-06-13 14:00:00') 

DECLARE @Start TIME, @End TIME 
SET @Start = '23:01:00' 
SET @End = '13:25:00' 

Вы можете изменить < к < = и> to> = включить его.

1

Идея решения состоит в том, чтобы переместить время в тот же день. Это выглядит следующим образом:

declare @startTime time='22:00' 
     ,@endTime time='2:00' 
     ,@shift int 
select @shift= case when @startTime>@endTime then DATEDIFF(ss,@startTime,'23:59:59')+ 1 
       else 0 end 

select cast(dateField as time) timeField, something 
from table1 
where dateadd(ss,@shift, cast(dateField as time)) between 
    dateadd(ss,@shift,@startTime) and dateadd(ss,@shift,@endTime) 

Или, если вы хотите в одном запросе:

declare @startTime time='22:00' 
     ,@endTime time='2:00' 

;with s as (
select case when @startTime>@endTime then DATEDIFF(ss,@startTime,'23:59:59')+ 1 
       else 0 end shift 
) 
select cast(dateField as time) timeField, something 
from table1 cross join s 
where dateadd(ss,s.shift, cast(dateField as time)) between 
    dateadd(ss,s.shift,@startTime) and dateadd(ss,s.shift,@endTime) 
+0

Мои два цента: первый запрос может быть дополнительно улучшен с помощью предварительной перестановки переменных @startTime и @endTime, так что 'WHERE' выглядит немного чище. – Alex

Смежные вопросы