Сравнить временную часть типа данных DateTime в SQL Server 2005 - PullRequest
10 голосов
/ 04 января 2010

Как можно сравнить только временную часть типа данных 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))

Ответы [ 5 ]

13 голосов
/ 05 января 2010
SELECT *
FROM Table1
WHERE DATEADD(day, -DATEDIFF(day, 0, MyDateField), MyDateField) > '12:30:50.400'
5 голосов
/ 04 января 2010

Как насчет этого?

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 также имеет «части» для минут, секунд и так далее. Конечно, вы можете использовать столько частей даты в предложении WHERE, сколько захотите.

1 голос
/ 04 января 2010

Другие опубликовали альтернативные методы формирования запроса, но я хочу ответить на то, что вы говорите в первом абзаце:

Следующий пример очень длинный и , вероятно, не быстрый способ сделать это.

По производительности, на самом деле не имеет значения, есть ли у вас один DATEPART или 10 DATEPARTS; тот факт, что у вас есть даже один DATEPART, ухудшает производительность.

Если вам нужно сравнивать по времени, а не по дате, тогда комментарий Лассе прямо о деньгах - вам нужно нормализовать в отдельные столбцы даты / времени. Фактически, SQL 2008 вводит типы date и time и рекомендует использовать их вместо datetime. У вас нет этого в SQL 2005, но вы можете обойти это, скажем, с помощью поля тиков для времени суток и проверочного ограничения, которое обнуляет все даты в столбце даты.

Если вам позже потребуется выполнить фильтры для полной даты + времени, легко создать вычисляемый столбец, и, если для них важна производительность, вы можете сохранить этот столбец и создать для него индекс.

1 голос
/ 04 января 2010

Что я хотел сделать, это извлечь временную часть типа данных DateTime и сравнить ее. Я нашел способ извлечь часть даты здесь в StackOverflow . Если у меня есть только часть даты, она просто вычитает дату из источника DateTime:

datePortion = DATEADD (день, DATEDIFF (день, 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. Сравнение плана выполнения показывает, что это самый быстрый способ сделать это. Я также проверил реальное время выполнения запроса ... не существует заметного быстрого метода.

0 голосов
/ 04 января 2010

конвертировать (varchar (10), MyDate, 108)

Это дает вам временную строку в формате ЧЧ: ММ: СС.

Затем вы можете сделать любое сравнение с ним

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