SQL, Анализ данных

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

Время прочтения: 4 мин.

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

Написав запрос на SQL, с помощью оператора BETWEEN, каково же было моё удивление, когда в результатах выгрузки не оказалось таких марок авто, как DATSUN и DAEWOO, которые точно были в базе данных.

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

Пример:

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

Таблица table1:

ID LAST_NAME FIRST_NAME MODEL_CAR YEAR
1 Иванов Петр Audi 2010
2 Петров Иван BMW 2015
3 Сидоров Василий Dodge 2017
4 Алексеев Олег D 2019
5 Михайлов Алексей Chevrolet 2012
6 Петрова Ольга Jeep 2015
7 Иванова Юлия Volvo 2016
8 Лужин Алексей Mersedes 2014
9 Абрамов Александр Ford 2017
10 Семенов Семен Datsun 2017

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

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

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

ID LAST_NAME FIRST_NAME MODEL_CAR YEAR
1 Иванов Петр Audi 2010
2 Петров Иван BMW 2015
5 Михайлов Алексей Chevrolet 2012
4 Алексеев Олег D 2019

Как видно из примера, выведены только значения, начинающиеся с А до С, за исключением строчки, где значение равно 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’
ID LAST_NAME FIRST_NAME MODEL_CAR YEAR
1 Иванов Петр Audi 2010
2 Петров Иван BMW 2015
5 Михайлов Алексей Chevrolet 2012
4 Алексеев Олег D 2019
10 Семенов Семен Datsun 2017
3 Сидоров Василий Dodge 2017

Такой нюанс существует только при работе с символьными данными, поэтому нужно быть внимательным, даже при работе с таким простым оператором, как 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')

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

Советуем почитать