Ошибка преобразования даты «Значение вне диапазона», преобразование даты в соответствии с предложением WHERE - PullRequest
0 голосов
/ 11 февраля 2020

Я работаю с таблицей, в которой значения даты хранятся в виде целых чисел в отдельных столбцах «век», «год», «месяц» и «день». (Столбец «Год» содержит только две последние цифры года, а столбец «Век» - от 0 до 1 для годов до 2000 и соответственно после 2000 года.)

Я пытаюсь отфильтровать данные после конкретная c дата. Эти столбцы должны быть преобразованы в одно значение даты или даты / времени, чтобы его можно было изменить для параметров отчета. Прямо сейчас предложение WHERE выглядит следующим образом:

WHERE convert(datetime, CAST( ((19 + Table.Century) * 100 + Table.Year) as varchar) + '-' +  (Table.Month as varchar) + '-' + CAST(Table.Day as varchar), 121) > Convert(datetime,'2020-01-01', 121)

Однако, когда я пытаюсь выполнить запрос, он всегда выдает ошибку:

Преобразование типа данных varchar к типу данных datetime, приведшему к значению, выходящему за пределы допустимого диапазона.

Кажется, что в столбце Месяц проблема l ie. Если я подставлю какой-либо 30-дневный месяц (или февраль) в значение Table.Month, оно выдаст ошибку. 31-дневные месяцы работают нормально. Тем не менее, в самих данных нет дат вне срока действия. Кроме того, оператор работает нормально и не ломается, если я помещаю его в оператор SELECT.

У меня складывается впечатление, что оператор WHERE оценивает каждое возможное значение Day по каждому возможному значению Month для каждого возможного значения Year, и т. Д. c. и заканчивает проверку на даты, такие как «2020-02-30». Как мне заставить это остановить это поведение?

1 Ответ

0 голосов
/ 11 февраля 2020

Использование datefromparts():

where datefromparts(1900 + century * 100 + year, month, day) > '2020-01-01'

Тем не менее, у вас могут быть недопустимые значения. Вы должны исследовать это:

select century, year, month, day
from t
where try_convert(concat(1900 + century * 100 + year, '-'
                         month, '-', day)
                 ) is null

Это работает, потому что SQL Сервер хорош для интерпретации дат, таких как '2020-1-1'.

...