sql-server Очень странный случай в datetime - PullRequest
0 голосов
/ 04 мая 2018

У меня есть эта таблица WorkTBL

id  MyDate      Tdate
84  27/04/2018  2018-04-27 13:35:09.000
85  27/04/2018  2018-04-27 13:35:09.000
86  27/04/2018  2018-04-27 13:35:09.000
88  27/04/2018  2018-04-27 13:36:06.000
89  27/04/2018  2018-04-27 13:36:06.000
90  27/04/2018  2018-04-27 13:36:06.000
91  27/04/2018  2018-04-27 13:36:06.000
92  27/04/2018  2018-04-27 13:40:00.000
93  27/04/2018  2018-04-27 13:40:00.000
95  02/05/2018  2018-05-02 16:03:22.000
96  02/05/2018  2018-05-02 16:03:22.000
98  02/05/2018  2018-05-02 16:04:35.000
102 04/05/2018  2018-05-04 22:57:42.000
103 04/05/2018  2018-05-04 22:57:42.000
104 04/05/2018  2018-05-04 22:57:42.000

Я пытаюсь найти записи в период с 01/03/2018 по 03/05/2018

я пробую это:

select id,CONVERT(VARCHAR(10),Tdate,103),Tdate from WorkTBL
 where (CONVERT(VARCHAR(10),Tdate,103) >= '01/03/2018' and  CONVERT(VARCHAR(10),Tdate,103)  <= '03/05/2018') 

и это:

select id,CONVERT(VARCHAR(10),Tdate,103),Tdate from WorkTBL
  where (CONVERT(VARCHAR(24),Tdate,103) between '01/03/2018' and  '03/05/2018')  order by id desc 

но я получаю только эти записи:

95  02/05/2018  2018-05-02 16:03:22.000
96  02/05/2018  2018-05-02 16:03:22.000
98  02/05/2018  2018-05-02 16:04:35.000

Где остальные? Почему я не получаю 88 27/04/2018 2018-04-27 13:36:06.000 например

спасибо

Ответы [ 3 ]

0 голосов
/ 04 мая 2018

Не преобразовывать дату / время в строки для сравнения!

Перейти на:

select id, CONVERT(VARCHAR(10), Tdate,1 03), Tdate
from WorkTBL
where Tdate >= '2018-01-03' and 
      Tdate < '2018-05-04'

Во-первых, ваши сравнения строк . Строки сравниваются в алфавитном порядке, что объясняет ваши результаты.

Во-вторых, не используйте between с датами и временем. Аарон Бертран имеет очень хороший блог на эту тему.

В-третьих, я удалил преобразование в дату. Как правило, использование функций или преобразований в столбце предотвращает использование индексов. Одним из очень немногих исключений является преобразование даты и времени в дату. Однако код все еще проще и чище без преобразования.

0 голосов
/ 05 мая 2018

Правильный ответ уже принят, но, чтобы ясно понять вашу проблему, используйте это:

select 
     [id]       =   [id]
    ,[MyDate]   =   convert(datetime, [MyDate], 103)
    ,[Tdate]    =   convert(datetime, [Tdate], 121)
from
    [#WorkTBL]
where
        convert(datetime, [Tdate], 121) >  convert(datetime, '01/03/2018', 103)
    and convert(datetime, [Tdate], 121) <  convert(datetime, '03/05/2018', 103);

Полный запрос на тестирование: https://pastebin.com/Csk1nHsC

0 голосов
/ 04 мая 2018

Всегда использовать ANSI SQL Стандартный формат даты ГГГГММДД

select id, CONVERT(VARCHAR(10),Tdate,103) Tdate 
from WorkTBL
where cast(Tdate as date) >= '20180103' and  
      cast(Tdate as date) <= '20180503'
order by id desc; 
...