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

Логически нет никакой разницы. С точки зрения производительности, как правило, на большинстве СУБД нет никакой разницы.

Ответ 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 и упорядочивая сравнения соответственно.

Один из вариантов использования, который у меня есть, - это запрос большого исторического набора данных с неиндексированными датами для записей в пределах определенного интервала. При написании запроса у меня будет хорошее представление о том, существует ли больше данных ДО указанного интервала или ПОСЛЕ указанного интервала, и могу ли я соответствующим образом упорядочить свои сравнения. Время выполнения сократилось вдвое в зависимости от размера набора данных, сложности запроса и количества записей, отфильтрованных при первом сравнении.