Запрос T-SQL, возвращающий элементы, которых не должно быть - PullRequest
2 голосов
/ 02 октября 2009

Вот сценарий. Столбец, о котором идет речь, называется datein, а его тип - datetime. У меня есть три строки со значением «2009-10-01 00: 00: 00.000» для «datein». Почему этот запрос возвращает вышеупомянутые строки?

SELECT  *
FROM    t_call AS tc
WHERE   tc.datein >= '2009-09-30 00:00:00.000'
        AND tc.datein <= '2009-09-30 23:59:59.999'

Использование

SELECT  *
FROM    t_call AS tc
WHERE   tc.datein BETWEEN '2009-09-30 00:00:00.000'
        AND '2009-09-30 23:59:59.999'

возвращает тот же результат

Ответы [ 5 ]

7 голосов
/ 02 октября 2009

Это отсутствие точности в тысячных долях второго значения. Попробуйте ".997" вместо этого.

Документация MSDN DateTime

Запустите это, и вы увидите:

declare @dt datetime

select @dt = '2009-09-30 23:59:59.999'
select @dt
3 голосов
/ 02 октября 2009

Точность DATETIME составляет 0,00333 секунды. Итак, вам нужно перейти к «2009-09-30 23: 59: 59.998», чтобы оно не округлялось до 1 октября.

Например:

select '2009-09-30 23:59:59.994', 
  cast('2009-09-30 23:59:59.994' as datetime)
union all select '2009-09-30 23:59:59.995', 
  cast('2009-09-30 23:59:59.995' as datetime)
union all select '2009-09-30 23:59:59.996', 
  cast('2009-09-30 23:59:59.996' as datetime)
union all select '2009-09-30 23:59:59.997', 
  cast('2009-09-30 23:59:59.997' as datetime)
union all select '2009-09-30 23:59:59.998', 
  cast('2009-09-30 23:59:59.998' as datetime)
union all select '2009-09-30 23:59:59.999', 
  cast('2009-09-30 23:59:59.999' as datetime)

возвращается:

2009-09-30 23:59:59.994 2009-09-30 23:59:59.993
2009-09-30 23:59:59.995 2009-09-30 23:59:59.997
2009-09-30 23:59:59.996 2009-09-30 23:59:59.997
2009-09-30 23:59:59.997 2009-09-30 23:59:59.997
2009-09-30 23:59:59.998 2009-09-30 23:59:59.997
2009-09-30 23:59:59.999 2009-10-01 00:00:00.000
0 голосов
/ 02 октября 2009

Безопасный способ написать эти запросы:

SELECT  *
FROM    t_call AS tc
WHERE   tc.datein >= '2009-09-30T00:00:00.000'
        AND tc.datein < '2009-10-01T00:00:00.000''
0 голосов
/ 02 октября 2009

Согласно документации MSDN

Данные о дате и времени с 1 января, С 1753 по 31 декабря 9999 г. Точность одной трехсотой второй (эквивалент 3,33 миллисекунды или 0,00333 секунды). Значения округлены с приращением .000, .003 или .007 секунд, как показано в таблице.

Из приведенного примера на этой странице вы должны завершить запрос 0,999, чтобы получить ожидаемые результаты.

0 голосов
/ 02 октября 2009

Какой тип столбца? Если это дата и время, попробуйте привести значения, с которыми вы сравниваете, к дате и времени; если это строка (char, nchar, varchar, nvarchar), какое сопоставление и т. д. вы используете для столбца?

...