SQL: МЕЖДУ против <= и> = - PullRequest
       33

SQL: МЕЖДУ против <= и> =

94 голосов
/ 27 октября 2009

В 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'

(Изменить: вторая дата события изначально отсутствовала, поэтому запрос был синтаксически неправильным)

Ответы [ 10 ]

99 голосов
/ 27 октября 2009

Они идентичны: BETWEEN является сокращением для более длинного синтаксиса в вопросе.

Используйте альтернативный более длинный синтаксис, где BETWEEN не работает, например,

Select EventId,EventName from EventMaster
where EventDate >= '10/15/2009' and EventDate < '10/18/2009'

(Примечание < вместо <= во втором состоянии.)

31 голосов
/ 27 октября 2009

Они одинаковы.

Следует быть осторожным, если вы используете это значение для DATETIME, совпадение даты окончания будет началом дня:

<= 20/10/2009

не совпадает с:

<= 20/10/2009 23:59:59

(это будет совпадать с <= 20/10/2009 00:00:00.000)

13 голосов
/ 27 октября 2009

Хотя BETWEEN легко читать и поддерживать, я редко рекомендую его использовать, потому что это закрытый интервал, и, как упоминалось ранее, это может быть проблемой с датами - даже без временных компонентов.

Например, при работе с месячными данными часто сравнивают даты BETWEEN first AND last, но на практике это обычно легче написать dt >= first AND dt < next-first (что также решает проблему временной части) - поскольку определение last обычно на один шаг больше, чем определение next-first (путем вычитания дня).

Кроме того, еще одна проблема заключается в том, что нижнюю и верхнюю границы необходимо указывать в правильном порядке (т.е. BETWEEN low AND high).

4 голосов
/ 27 октября 2009

Как упомянуто @marc_s, @Cloud, et al. они в основном одинаковы для закрытого диапазона.

Но любые дробные значения времени могут вызвать проблемы с закрытым диапазоном (большим или равным и меньшим или равным ), а не с полуоткрытым диапазоном (большим или равным и меньше ) с конечным значением после последнего возможного момента.

Таким образом, чтобы избежать переписывания запроса как:

SELECT EventId, EventName
  FROM EventMaster
 WHERE (EventDate >= '2009-10-15' AND
        EventDate <  '2009-10-19')    /* <<<== 19th, not 18th */

Поскольку BETWEEN не работает с полуоткрытыми интервалами, я всегда внимательно смотрю на любой запрос даты / времени, который его использует, поскольку, вероятно, это ошибка.

4 голосов
/ 27 октября 2009

Как правило, нет никакой разницы - ключевое слово BETWEEN поддерживается не на всех платформах СУБД, но если это так, два запроса должны быть идентичны.

Поскольку они идентичны, на самом деле нет различий в скорости или чем-то еще - используйте ту, которая кажется вам более естественной.

3 голосов
/ 27 октября 2009

У меня есть небольшое предпочтение для 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, конечно, это будет синтаксическая ошибка и будет быстро исправлена.

3 голосов
/ 27 октября 2009

Я думаю, что единственная разница - это количество синтаксического сахара в каждом запросе. МЕЖДУ просто изящный способ сказать точно так же, как второй запрос.

Возможно, есть какая-то особая разница в СУБД, о которой я не знаю, но я так не думаю.

2 голосов
/ 27 октября 2009

См. отличное сообщение в блоге из Аарон Бертран о том, почему вы должны изменить формат строки и как обрабатываются граничные значения в запросах диапазона дат.

2 голосов
/ 27 октября 2009

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

0 голосов
/ 07 февраля 2019

Отказ от ответственности: все, что ниже, является лишь анекдотическим и основано на моем личном опыте. Любой, кто захочет провести более тщательный эмпирический анализ, может выполнить его и проголосовать за меня, если я. Я также знаю, что SQL является декларативным языком, и вам не нужно учитывать, как обрабатывается ваш код при его написании, но, поскольку я ценю свое время, я делаю.

Существует бесконечно логически эквивалентные утверждения, но я рассмотрю три (иш).

Случай 1: два сравнения в стандартном порядке (порядок оценки фиксирован)

A> = MinBound AND A <= MaxBound </p>

Случай 2: синтаксический сахар (порядок оценки не выбран автором)

A МЕЖДУ MinBound И MaxBound

Случай 3: два сравнения в образованном порядке (порядок оценки, выбранный во время записи)

A> = MinBound AND A> = MaxBound

или

A> = MaxBound AND A> = MinBound

По моему опыту, Случай 1 и Случай 2 не имеют каких-либо последовательных или заметных различий в производительности, поскольку они не знают набор данных.

Однако вариант 3 может значительно сократить время выполнения. В частности, если вы работаете с большим набором данных и имеете некоторые эвристические знания о том, будет ли A более вероятным, чем MaxBound или меньше, чем MinBound Вы можете значительно улучшить время выполнения, используя Case 3 и упорядочив сравнения соответственно.

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

...