На что стоит обратить внимание, применяя оператор between в SQL?

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

В ходе работы с одной из БД, содержащих данные о транспортных средствах, возникла необходимость выгрузить модели автотранспорта, названия которых начинаются в диапазоне от «А» до «D».

Написав запрос на SQL, с помощью оператора between,в результатах выгрузки не оказалось таких марок авто, как datsun и daewoo, которые точно были в базе данных.

Начав разбираться, стало понятно следующее — если Вам нужно применить оператор between, который выбирает при запросе все значения из заданного диапазона (включая границы), то с датами и числовыми значениями не возникает трудностей, а вот с текстовыми строками всё иначе т.к. значение верхней границы диапазона не будет включено в выборку, если оно не указано точно.

Пример:

Итак, у нас есть таблица «table1» со столбцом «model_car» (тип данных varchar) из которой нам необходимо вывести ее часть, где названия марок автомобилей лежат в диапазоне от А до D.

Таблица table1:

На что стоит обратить внимание, применяя оператор between в SQL?

Если выполнить следующий запрос:

SELECT * FROM table1 WHERE model_car BETWEEN ‘A’ AND ‘D’ ORDER BY model_car

То результат его выполнения будет следующим:

На что стоит обратить внимание, применяя оператор between в SQL?

Как видно из примера, выведены только значения, начинающиеся с А до С, за исключением строчки, где значение равно D.

Дело в том, что так оператор between сравнивает строки неравной длины. Строка «D» короче строки «Dodge» и, при сравнении, дополняется пробелами. Но при сортировке по алфавиту пробелы окажутся опережающими символами и поэтому строка в выборку не попадает.

Выражение «Имя» between ‘A’AND ‘D’эквивалентно «имя» >= ‘A’AND «имя» <= ‘D’

То есть, «Audi» и «Chevrolet» это >= ‘A’AND <= ‘D’, что удовлетворяет условию, но «Dodge» — это не <= ‘D’. «Dodge» — это > ‘D’.

Чтобы получить все строки, начинающиеся от А до D включительно, то необходимо было в запросе написать так:

model_car BETWEEN ‘A’ AND ‘E’
На что стоит обратить внимание, применяя оператор between в SQL?

Такой нюанс существует только при работе с символьными данными, поэтому нужно быть внимательным, даже при работе с таким простым оператором, как between.

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

  • через операторы сравнения. Операторы сравнения – это математические символы, которые указывают на определенный тип сравнения между двумя значениями (= равно; > больше; < меньше; >= больше или равно; <= меньше или равно; <> не равно)
SELECT * FROM table1 WHERE MODEL_CAR <‘E’
  • через оператор LIKE. Оператор LIKE используется для того, чтобы находить значение по определённому шаблону. В качестве условия он использует групповые символы, которые могут соответствовать чему-нибудь. Например, знак подчеркивания (_) замещает собой одиночный символ, а знак процента (%) позволяет нам сопоставлять строку любой длины.
SELECT * FROM table1 WHERE MODEL_CAR LIKE 'A%' or MODEL_CAR LIKE 'B%' or MODEL_CAR LIKE 'C%' or MODEL_CAR LIKE 'D%'
  • через функцию substring и оператор IN. Функция substring извлекает из выражения, которое мы указываем, часть заданной длины начиная от заданной позиции. В нашем случае мы указываем столбец с названиями автомобилей и выделяем только первую букву. Далее через оператора IN определяем набор значений, в который данное значение может быть включено, т.е. указываем перечень автомобилей, которые начинаются с А, В, С, D.
SELECT *, SUBSTRING (MODEL_CAR,1,1) FROM table1 where SUBSTRING (MODEL_CAR,1,1) IN ('A', 'B', 'C', 'D')

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

11
2 комментария

Насколько это формат vc не знаю, но почему table1, нет более подходящего названия, чтобы понять про что это таблица и почему она денормализована?)
Ну и если вы в запросах функции используете почему в between тоже применить и тогда будет читаемо?

Ответить

Более простое и быстрое решение через LIKE:
SELECT * FROM table1
WHERE model LIKE '[A-D]%'

Ответить