Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Сравнение величин типа smalldatetime и datetime  [new]
ASD.Rapax
Member

Откуда:
Сообщений: 52
Есть таблица, содержащая поле типа datetime, отражающее время наступления какого-либо события.
Задача тривиальна - получить все события за определенный промежуток. Для этого надо сравнивать заданные пользователем границы промежутка со значениями datetime в указанной таблице.
Вижу два варианта решения:
1.
...
WHERE MyTable.EventStamp >= @BeginStamp 
  AND MyTable.EventStamp <= @EndStamp
...
2.
... 
WHERE DATEPART(dy, MyTable.EventStamp) >= DATEPART(dy, @BeginStamp) 
  AND DATEPART(dy, MyTable.EventStamp) <= DATEPART(dy, @EndStamp)
...

Первый вариант дает возможность задавать промежуток с большой точностью, второй - только по дням (да и то внутри одного года). однако мне видится второй вариант более быстродейственным, так как сравниваются значения типа int. С другой стороны, следует учитывать вызов функции datepart для каждого выбираемого значения и то, что операция сравнения "в лоб" наверняка оптимизированна исходя из физ представления типов smalldatetime и datetime. Так что у меня сомнения, какой вариант быстрей. Само собой первый вариант предпочтительней.

ЗЫ. Я вообще не очень опытен, но мне кажется, что в случае низкого быстродействия может помочь индекс по полю EventStamp. Я прав?
11 июл 09, 13:56    [7404832]     Ответить | Цитировать Сообщить модератору
 Re: Сравнение величин типа smalldatetime и datetime  [new]
iap
Member

Откуда: Москва
Сообщений: 46975
ASD.Rapax,

странно слышать о преимуществе сравнения данных типа int и datetime,
когда видишь ограничение, накладываемое на функцию от поля.

Советую забыть ассемблер, и познакомиться, например, с таким понятием как "индекс".
DATEPART(dy, MyTable.EventStamp) >= DATEPART(dy, @BeginStamp)
сразу отвергает возможность использовать индекс по MyTable.EventStamp (если он есть, конечно).
Ибо индекс в MS SQL строится только по полям таблицы, а не по выражениям.

Лучше
2.
... 
WHERE MyTable.EventStamp >= DATEADD(DAY,  DATEDIFF(DAY,0,@BeginStamp),0)
  AND MyTable.EventStamp <  DATEADD(DAY,1+DATEDIFF(DAY,0,@EndStamp),0)
...
Версия сервера какая? Если SQL2008, то рассмотрите ещё тип DATE
11 июл 09, 14:22    [7404851]     Ответить | Цитировать Сообщить модератору
 Re: Сравнение величин типа smalldatetime и datetime  [new]
ASD.Rapax
Member

Откуда:
Сообщений: 52
Про индекс я относительно первого варинат спрашивал, извиняюсь, что не уточнил это.

Тогда лучше:
... 
WHERE MyTable.EventStamp > DATEADD(DAY, DATEDIFF(DAY,0,@BeginStamp) - 1,0)
  AND MyTable.EventStamp < DATEADD(DAY, DATEDIFF(DAY,0,@EndStamp)   + 1,0)
...
:-)

Так кто быстрей из указанных мной вариантов будет?
11 июл 09, 22:52    [7405339]     Ответить | Цитировать Сообщить модератору
 Re: Сравнение величин типа smalldatetime и datetime  [new]
iap
Member

Откуда: Москва
Сообщений: 46975
ASD.Rapax
Про индекс я относительно первого варинат спрашивал, извиняюсь, что не уточнил это.

Тогда лучше:
... 
WHERE MyTable.EventStamp > DATEADD(DAY, DATEDIFF(DAY,0,@BeginStamp) - 1,0)
  AND MyTable.EventStamp < DATEADD(DAY, DATEDIFF(DAY,0,@EndStamp)   + 1,0)
...
:-)

Так кто быстрей из указанных мной вариантов будет?
Ваша "доработка" запроса неверна, ибо оставляет даты (с ненулевым временем) из предыдущего дня.
Вообще-то главная идея была - ограничить поле DATETIME так, чтобы при этом не учитывалось время.
Ясно, что дата с любым временем меньше 0 часов следующего дня.
Поэтому и прибавлялся один день.
12 июл 09, 11:15    [7405643]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить