Зачем использовать оператор BETWEEN, если можно обойтись без него?

StackOverflow https://stackoverflow.com/questions/1960801

  •  21-09-2019
  •  | 
  •  

Вопрос

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

SELECT *
FROM employees
WHERE salary BETWEEN 5000 AND 15000;

SELECT *
FROM employees
WHERE salary >= 5000
AND salary <= 15000;
Это было полезно?

Решение

BETWEEN может помочь избежать ненужной переоценки выражения:

SELECT  AVG(RAND(20091225) BETWEEN 0.2 AND 0.4)
FROM    t_source;

---
0.1998

SELECT  AVG(RAND(20091225) >= 0.2 AND RAND(20091225) <= 0.4)
FROM    t_source;

---
0.3199

t_source это просто фиктивный стол с 1,000,000 записи.

Конечно, это можно обойти с помощью подзапроса, но в MySQL это менее эффективно.

И конечно, BETWEEN более читабелен.Занимает 3 раз использовать его в запросе, чтобы запомнить синтаксис навсегда.

В SQL Server и MySQL, LIKE против константы с неведущим '%' также является сокращением для пары >= и <:

SET SHOWPLAN_TEXT ON
GO
SELECT  *
FROM    master
WHERE   name LIKE 'string%'
GO
SET SHOWPLAN_TEXT OFF
GO


|--Index Seek(OBJECT:([test].[dbo].[master].[ix_name_desc]), SEEK:([test].[dbo].[master].[name] < 'strinH' AND [test].[dbo].[master].[name] >= 'string'),  WHERE:([test].[dbo].[master].[name] like 'string%') ORDERED FORWARD)

Однако, LIKE синтаксис более разборчив.

Другие советы

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

BETWEEN в T-SQL поддерживает оператор NOT, поэтому вы можете использовать такие конструкции, как

WHERE salary not between 5000 AND 15000; 

По-моему, человеку тогда понятнее

WHERE salary < 5000 OR salary > 15000;

И, наконец, если вы введете имя столбца только один раз, у вас будет меньше шансов совершить ошибку.

Версия с «между» читается легче.Если бы я использовал вторую версию, я бы, вероятно, написал ее как

5000 <= salary and salary <= 15000

по той же причине.

Я голосую за @Quassnoi — правильность — это большая победа.

Я обычно нахожу литералы более полезными, чем синтаксические символы, такие как <, <=, >, >=, != и т. д.Да, нам нужны (лучшие и точные) результаты.И, по крайней мере, я избавляюсь от вероятности неправильной интерпретации и изменения значений символов визуально.Если вы используете <= и чувствуете логически неправильный вывод, поступающий из вашего запроса на выборку, вы можете некоторое время бродить и прийти только к выводу, что вы написали <= вместо >= [визуальная неправильная интерпретация?].Надеюсь, я ясно выразился.

И не сокращаем ли мы код (вместе с тем, чтобы он выглядел более высокоуровневым), что означает более лаконичный и простой в обслуживании?

SELECT * 
FROM emplyees 
WHERE salary between 5000 AND 15000; 



SELECT * 
FROM emplyees 
WHERE salary >= 5000 AND salary <= 15000; 

Первый запрос использует всего 10 слов, а второй — 12!

Лично я бы не использовал BETWEEN, просто потому, что, похоже, нет четкого определения того, следует ли включать или исключать значения, которые служат для ограничения условия, в вашем данном примере:

SELECT *
FROM emplyees
WHERE salary between 5000 AND 15000;

Диапазон мог включить 5000 и 15000, или это мог исключить их.

Синтаксически я думаю, что их следует исключить, поскольку сами значения нет между данные числа.Но мое мнение именно таково, тогда как использование таких операторов, как >= очень специфичен.И менее вероятно, что они будут меняться между базами данных или между их приращениями/версиями.


Отредактировано в ответ на комментарии Павла и Джонатана.

Как заметил Павел, ANSI SQL (http://www.contrib.andrew.cmu.edu/~shadow/sql/sql1992.txt) еще в 1992 году требует, чтобы конечные точки учитывались в пределах возвращаемой даты и были эквивалентны X >= lower_bound AND X <= upper_bound:

8.3

     Function

     Specify a range comparison.

     Format

     <between predicate> ::=
          <row value constructor> [ NOT ] BETWEEN
            <row value constructor> AND <row value constructor>


     Syntax Rules

     1) The three <row value constructor>s shall be of the same degree.

     2) Let respective values be values with the same ordinal position
        in the two <row value constructor>s.

     3) The data types of the respective values of the three <row value
        constructor>s shall be comparable.

     4) Let X, Y, and Z be the first, second, and third <row value con-
        structor>s, respectively.

     5) "X NOT BETWEEN Y AND Z" is equivalent to "NOT ( X BETWEEN Y AND
        Z )".

     6) "X BETWEEN Y AND Z" is equivalent to "X>=Y AND X<=Z".

Если конечные точки инклюзивны, то BETWEEN является предпочтительным синтаксисом.

Меньше ссылок на столбец означает меньше мест для обновления, когда что-то меняется.Это инженерный принцип: меньше вещей означает, что меньше вещей может сломаться.

Это также означает меньшую вероятность того, что кто-то поставит неправильную скобку для таких вещей, как включение ИЛИ.ИЕ:

WHERE salary BETWEEN 5000 AND (15000
  OR ...)

... вы получите ошибку, если поместите скобки вокруг части AND оператора BETWEEN.Против:

WHERE salary >= 5000
 AND (salary <= 15000
  OR ...)

...вы узнаете о проблеме только тогда, когда кто-то просматривает данные, полученные в результате запроса.

Семантически эти два выражения имеют одинаковый результат.

Однако, BETWEEN представляет собой один предикат, а не два предиката сравнения в сочетании с AND.В зависимости от оптимизатора, предоставляемого вашей СУБД, один предикат может быть проще оптимизировать, чем два предиката.

Хотя я ожидаю, что большинство современных реализаций СУБД должен оптимизируйте оба выражения одинаково.

хуже, если это

  SELECT id FROM entries 
  WHERE 
     (SELECT COUNT(id) FROM anothertable WHERE something LEFT JOIN something ON...) 
     BETWEEN entries.max AND entries.min;

Перепишите это, используя свой синтаксис, не используя временное хранилище.

Мне лучше использовать второй, так как вы всегда знаете, это <= или <.

В SQL я согласен, что BETWEEN в большинстве случаев не нужен и может быть синтаксически эмулирован с помощью 5000 <= salary AND salary <= 15000.Это также ограничено;Я часто хочу применить включающую нижнюю границу и исключительную верхнюю границу: @start <= when AND when < @end, с которым вы не можете сделать BETWEEN.

OTOH, BETWEEN удобен, если проверяемое значение является результатом сложного выражения.

Было бы неплохо, если бы SQL и другие языки последовали примеру Python в использовании правильной математической записи: 5000 <= salary <= 15000.

Один небольшой совет, который сделает ваш код более читабельным:используйте < и <= вместо > и >=.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top