SQL Server 2005 - запросите интервал времени в диапазоне дат - PullRequest
1 голос
/ 29 марта 2011

У меня есть столбец DateTime. Я хочу извлечь все записи, скажем, с 8:30 до 16:15 в пределах определенного диапазона дат. Моя проблема в том, что мне нужно сравнивать часы и минуты как одно значение времени. Я могу проверить значение параметра DATEPART для значения «Больше или меньше чем несколько часов», но если я сделаю это в течение нескольких минут, мой запрос не будет выполнен, если время в конце дня будет иметь меньшее значение в минутах.

Я посмотрел на INTERVAL, BETWEEN, DATEPART, DATEDIFF и т. Д., Но не понимаю, как это сделать без значения «TimeOfDay», которое я могу использовать в записях разных дат.

Я попытался вычесть части даты года, месяца и дня, чтобы я мог сравнить только время суток, но при попытке вычесть, скажем, часть года даты, я получаю ошибку переполнения:

Эта часть работает:

select - cast( DATEPART(YEAR, CallTime) as integer) from history

Это не удалось:

select DATEADD(YEAR, - cast( DATEPART(YEAR, CallTime) as integer), CallTime) 
from history where calltime is not null

Я также пытался привести части часов и минут к символам, конкатенировать их и сравнить с моим целевым диапазоном, но это также не удается.

Я полагаю, что более новые версии SQL-сервера могут иметь функцию для решения этой ситуации, но это мне не доступно.

Я надеюсь и представляю, что есть простое, очевидное решение, но оно ускользает от меня.

Ответы [ 3 ]

2 голосов
/ 30 марта 2011

Попробуйте создать функцию «MinuteOfDay», которая вычисляет, сколько минут прошло в дне на основе даты и времени.

CREATE FUNCTION dbo.[MinuteOfDay] 
(
    @dt datetime
)
RETURNS int
AS
BEGIN
    RETURN (datepart(hh,@dt)*60) + datepart(mi,@dt) 
END

, а затем использовать результат этой функции для фильтрации.

select * 
from MyTable t 
where dbo.MinuteOfDay(t.SomeDateTimeColumn) between dbo.MinuteOfDay('1900-1-1 08:30:00') and dbo.MinuteOfDay('1900-1-1 16:15:00')
0 голосов
/ 30 марта 2011

Значения DATETIME могут быть приведены как FLOAT.На самом деле, DATETIME хранится как FLOAT.

Вся часть FLOAT - это дни с «12/31/1899» (или что-то близкое).Дробная часть - это количество часов, деленное на 24. Итак, 0,5 = 12 часов дня.

08: 30 - это 0,3541666667

16: 15 - это 0,6770833333

ВЫБЕРИТЕ CAST (CAST('2011-03-25 08:30:00' как дата) как плавать) = 40625.3541666667

выбрать CAST (CAST ('2011-03-25 16:15:00' как дата) как плавать)= 40625.6770833333

Таким образом, вы можете написать

SELECT * FROM пользователей WHERE hire_date <40625.3541666667 </p>

Используя DATETIME в качестве FLOAT, вы можете использовать любые математические функции, которые лучше всего подходят для вашего запроса.

0 голосов
/ 29 марта 2011

сделайте снимок:

DECLARE @StartDateTime  datetime
       ,@EndDateTime    datetime

--date range is ALL of January 1st up to & including 31st
SELECT @StartDateTime='2011/01/01'
      ,@EndDateTime='2011/01/31'

SELECT
    *
    FROM TableName  t
    WHERE 
        t.ColumnDate>=@StartDateTime AND t.ColumnDate<@EndDateTime+1 --date range
        AND LEFT(RIGHT(CONVERT(char(19),t.ColumnDate(),120),8),5)>='08:30' --time range start
        AND LEFT(RIGHT(CONVERT(char(19),t.ColumnDate(),120),8),5)<='16:15' --time range end

, если у вас есть индекс для t.ColumnDate, это должно быть в состоянии использовать его.

часть "диапазона дат"WHERE выбрасывает строки, которые не попадают в предполагаемый диапазон дат.Часть «начало временного диапазона» в WHERE отбрасывает строки, которые относятся к более раннему времени, а «конец временного диапазона» отбрасывает строки, которые находятся на более позднем этапе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...