Как я могу сравнить только часть времени Типа данных datetime в SQL Server 2005? Например, я хочу получить все записи, в которых MyDateField после определенного времени. Следующим примером является очень длинное и вероятно не быстрый способ сделать это. Я хочу все даты, где MyDateField больше, чем 12:30:50.400
SELECT *
FROM Table1
WHERE ((DATEPART(hour, MyDateField) = 12) AND (DATEPART(minute, MyDateField) = 30) AND (DATEPART(second, MyDateField) = 50) AND (DATEPART(millisecond, MyDateField) > 400))
OR ((DATEPART(hour, MyDateField) = 12) AND (DATEPART(minute, MyDateField) = 30) AND (DATEPART(second, MyDateField) > 50))
OR ((DATEPART(hour, MyDateField) = 12) AND (DATEPART(minute, MyDateField) > 30))
OR ((DATEPART(hour, MyDateField) > 12))
SELECT *
FROM Table1
WHERE DATEADD(day, -DATEDIFF(day, 0, MyDateField), MyDateField) > '12:30:50.400'
Я хотел извлечь временную часть типа данных DateTime и сравнить ее. Способ извлечь порцию даты я нашел здесь в StackOverflow. Если у меня есть только часть даты, это просто вычесть дату из источника DateTime:
datePortion = DATEADD(day, DATEDIFF(day,0, sourceDate), 0)
timePortion = DATEDIFF(миллисекунда, datePortion, sourceDate)
, поэтому макрос для извлечения временной части в SQL Server 2005:
f(x) = DATEDIFF(миллисекунда, DATEADD(день, DATEDIFF(день,0, sourceDate), 0), sourceDate))
Теперь запрос на сравнение временной части поля DateTime с 12:30:50.400:
SELECT *
FROM Table1
WHERE
DATEDIFF(millisecond, DATEADD(day, DATEDIFF(day, 0, DateTimeField), 0), DateTimeField)
>
DATEDIFF(millisecond, DATEADD(day, DATEDIFF(day, 0, '1900-01-01T12:30:50.400'), 0), '1900-01-01T12:30:50.400')
Я протестировал этот запрос с другими видами запросов, в том числе с использованием оператора вычитания ('-') и CONVERT. Сравнение плана выполнения указывает на то, что это самый быстрый метод. Также я проверил реальное время выполнения запроса... нет заметно более быстрого метода.
.Как насчет этого?
SELECT (fields)
FROM dbo.YourTable
WHERE DATEPART(HOUR, MyDate) >= 12
AND DATEPART(MINUTE, MyDate) >= 23
AND DATEPART(SECOND, MyDate) >= 45
Час указан в 24-часовом формате, например, 12 означает 12-часовой полдень, 15 означает 3 часа дня.
DATEPART
также имеет "части" для минут, секунд и так далее. Конечно, вы можете использовать столько частей даты в вашем пункте ГДЕ, сколько захотите.
Другие написали альтернативные методы формирования запроса, но я хочу ответить на то, что вы скажете в первом абзаце:
Следующий пример очень длинный и , вероятно, не быстрый способ сделать это.
С точки зрения производительности, не имеет значения, есть ли у вас один DATEPART
или 10 DATEPARTS
; то, что у вас есть хотя бы один DATEPART
- это то, что может повредить производительности.
Если вам нужно сравнить по времени, но не по дате, то комментарий Лассе прямо по деньгам - вам нужно нормализовать в отдельные столбцы даты/времени. На самом деле, в SQL 2008 введены типы date
и time
и рекомендовано использовать их вместо datetime
. В SQL 2005 этого нет, но вы можете работать с ним, скажем, с полем тиков для времени суток и ограничением проверки, которое заставляет все отделы данных столбца даты обнуляться.
Если позже вам понадобится выполнять фильтры на полную дату+время, то легко создать вычисленный столбец, а если для них проблема с производительностью, то вы можете сохранить этот столбец и создать на нем индекс.
.convert(varchar(10),MyDate,108)
Это дает вам временную строку формата HH:MM:SS.
Затем вы можете сделать с ним любое сравнение
.