использовать «между» с varchar (SQL Server) - PullRequest
3 голосов
/ 04 июня 2009

Использование SQL Server 2005 Express.

(
    CONVERT(VARCHAR(8), R.reviewStart, 108) between CONVERT(VARCHAR(8), M.meetingStart, 108) and CONVERT(VARCHAR(8), M.meetingEnd, 108) OR
    CONVERT(VARCHAR(8), R.reviewEnd, 108) between CONVERT(VARCHAR(8), M.meetingStart, 108) and CONVERT(VARCHAR(8), M.meetingEnd, 108) OR
    CONVERT(VARCHAR(8), M.meetingStart, 108) between CONVERT(VARCHAR(8), R.reviewStart, 108) and CONVERT(VARCHAR(8), R.reviewEnd, 108) OR
    CONVERT(VARCHAR(8), M.meetingEnd, 108) between CONVERT(VARCHAR(8), R.reviewStart, 108) and CONVERT(VARCHAR(8), R.reviewEnd, 108)
)

Будет ли "промежуточный" по-прежнему иметь ожидаемое поведение после того, как datetime был преобразован в varchar?

Спасибо

Ответы [ 3 ]

2 голосов
/ 04 июня 2009

Да, в зависимости от того, что вы подразумеваете под ожидаемым поведением. Оператор BETWEEN будет рассматривать эти операнды как varchars и соответственно применять свои правила сравнения:

МЕЖДУ возвращает ИСТИНА, если значение of test_expression больше или равно значению begin_expression и меньше или равно значению end_expression.

Теперь я вижу много потенциальных проблем, сравнивая строки и ожидая сравнения даты. Я не видел ни одного в своих тестах, но внимательно посмотрите на ваши данные. CONVERT возвращает 24-часовое время с соответствующими начальными нулями?

В этом вопросе есть и другие подходы к сравнению времени без даты, кроме преобразования их в varchars.

Кроме того, следите за нулевыми датами, что приведет к тому, что соответствующее условие WHERE вернет false (фактически, неизвестно).

В другом своем вопросе вы указали, что получаете ошибку. Если да, можете ли вы опубликовать это?

0 голосов
/ 04 июня 2009

Как я уже говорил в вашем другом посте, если возможно, вам следует рассмотреть возможность перехода на SQL 2008 из-за t новых типов даты и времени, которые позволяют явно разделять часть даты и часть времени , так что ваши выражения фильтра становятся намного проще и вы можете индексировать по времени. Так как его Экспресс, действительно не должно быть никаких причин, чтобы сдерживать вас в 2005 году.

0 голосов
/ 04 июня 2009

Ваше первое условие эквивалентно этому более дружественному к индексу:

R.reviewStart >=  DATEADD(day, DATEDIFF(day, '19010101', M.meetingStart), '19010101') 
and R.reviewStart < DATEADD(day, 1+DATEDIFF(day, '19010101', M.meetingStart), '19010101') 

(объяснено здесь: Повторное использование вашего кода с табличными UDF ) .

...