SQL: BETWEEN vs <= и> =
В SQL Server 2000 и 2005:
- В чем разница между этими двумя предложениями
WHERE
?
- какой из них мне следует использовать в каких сценариях?
Запрос 1:
SELECT EventId, EventName
FROM EventMaster
WHERE EventDate BETWEEN '10/15/2009' AND '10/18/2009'
Запрос 2:
SELECT EventId, EventName
FROM EventMaster
WHERE EventDate >='10/15/2009'
AND EventDate <='10/18/2009'
(Изменение: вторая дата события изначально отсутствовала, поэтому запрос был синтаксически неправильным)
Ответы
Ответ 1
Они идентичны: BETWEEN
является сокращением длинного синтаксиса в вопросе.
Используйте альтернативный более длинный синтаксис, где BETWEEN
не работает, например.
Select EventId,EventName from EventMaster
where EventDate >= '10/15/2009' and EventDate < '10/18/2009'
(Примечание <
, а не <=
во втором условии.)
Ответ 2
Они одинаковы.
Осторожно, стоит ли использовать это против DATETIME, совпадение даты окончания будет началом дня:
<= 20/10/2009
- это не то же самое, что:
<= 20/10/2009 23:59:59
(он будет соответствовать <= 20/10/2009 00:00:00.000
)
Ответ 3
Хотя BETWEEN
легко читается и поддерживается, я редко рекомендую его использовать, потому что это замкнутый интервал, и, как упоминалось ранее, это может быть проблемой с датами - даже без компонентов времени.
Например, при работе с месячными данными часто бывает сопоставлять даты BETWEEN first AND last
, но на практике обычно проще писать dt >= first AND dt < next-first
(что также решает проблему с временной частью) - поскольку определение last
обычно на один шаг дольше, чем определение next-first
(путем вычитания дня).
Кроме того, другой способ заключается в том, что нижняя и верхняя границы должны быть указаны в правильном порядке (т.е. BETWEEN low AND high
).
Ответ 4
Как правило, нет разницы - ключевое слово BETWEEN
не поддерживается на всех платформах РСУБД, но если это так, два запроса должны быть идентичными.
Поскольку они идентичны, на самом деле нет никакого различия с точки зрения скорости или чего-либо еще - используйте тот, который кажется вам более естественным.
Ответ 5
Как упоминалось @marc_s, @Cloud, et al. они в основном одинаковы для закрытого диапазона.
Но любые дробные значения времени могут вызывать проблемы с закрытым диапазоном (больше или равно и меньше или равно), в отличие от полуоткрытого диапазона (больше или равно и меньше) с конечным значением после последнего возможного момента.
Итак, чтобы избежать повторения запроса, выполните следующие действия:
SELECT EventId, EventName
FROM EventMaster
WHERE (EventDate >= '2009-10-15' AND
EventDate < '2009-10-19') /* <<<== 19th, not 18th */
Так как BETWEEN
не работает для полуоткрытых интервалов, я всегда смотрю на любой запрос даты/времени, который его использует, поскольку, вероятно, это ошибка.
Ответ 6
Я думаю, что единственное различие заключается в количестве синтаксического сахара в каждом запросе. BETWEEN - это просто гладкий способ сказать точно так же, как и второй запрос.
Может быть какая-то определенная разница в RDBMS, о которой я не знаю, но на самом деле я так не думаю.
Ответ 7
У меня есть небольшое предпочтение BETWEEN
, потому что он мгновенно очищает читателя от того, что вы проверяете одно поле для диапазона. Это особенно верно, если в вашей таблице есть похожие имена полей.
Если, скажем, наша таблица имеет как transactiondate
, так и transitiondate
, если я читаю
transactiondate between ...
Я сразу знаю, что оба конца теста относятся к этому одному полю.
Если я прочитал
transactiondate>='2009-04-17' and transactiondate<='2009-04-22'
Мне нужно сделать дополнительный момент, чтобы убедиться, что оба поля одинаковы.
Кроме того, поскольку запрос со временем редактируется, неаккуратный программист может отделить два поля. Я видел много запросов, которые говорят что-то вроде
where transactiondate>='2009-04-17'
and salestype='A'
and customernumber=customer.idnumber
and transactiondate<='2009-04-22'
Если они попробуют это с помощью BETWEEN
, конечно, это будет синтаксическая ошибка и оперативно исправлена.
Ответ 8
Логически нет никакой разницы.
С точки зрения производительности, как правило, на большинстве СУБД нет никакой разницы.
Ответ 9
Смотрите отличное сообщение в блоге от Аарон Бертран о том, почему вы должны изменить ваш формат строки и то, как граничные значения обрабатываются в запросах диапазона дат.
Ответ 10
Отказ от ответственности: все, что ниже, является лишь анекдотическим и взятым непосредственно из моего личного опыта. Любой, кто захочет провести более тщательный эмпирический анализ, может выполнить его и проголосовать за меня, если я. Я также знаю, что SQL является декларативным языком, и вам не нужно учитывать, КАК ваш код обрабатывается при его написании, но, поскольку я ценю свое время, я это делаю.
Есть бесконечные логически эквивалентные утверждения, но я рассмотрю три (иш).
Случай 1: два сравнения в стандартном порядке (порядок оценки фиксирован)
A> = MinBound AND A & lt; = MaxBound
Случай 2: синтаксический сахар (порядок оценки не выбран автором)
МЕЖДУ MinBound И MaxBound
Случай 3: два сравнения в образованном порядке (порядок оценки, выбранный во время записи)
A> = MinBound AND A & lt; = MaxBound
Или
A & lt; = MaxBound AND A> = MinBound
По моему опыту, Случай 1 и Случай 2 не имеют каких-либо последовательных или заметных различий в производительности, так как они не знают набор данных.
Тем не менее, случай 3 может значительно улучшить время выполнения. В частности, если вы работаете с большим набором данных и имеете некоторые эвристические знания о том, будет ли A более вероятным, чем MaxBound или меньше, чем MinBound вы можете заметно улучшить время выполнения, используя Case 3 и упорядочивая сравнения соответственно.
Один из вариантов использования, который у меня есть, - это запрос большого исторического набора данных с неиндексированными датами для записей в пределах определенного интервала. При написании запроса у меня будет хорошее представление о том, существует ли больше данных ДО указанного интервала или ПОСЛЕ указанного интервала, и могу ли я соответствующим образом упорядочить свои сравнения. Время выполнения сократилось вдвое в зависимости от размера набора данных, сложности запроса и количества записей, отфильтрованных при первом сравнении.