Сайт вебмастера

База SQLite и основы SQL. Часть 3 (фильтрация данных)

10-11-2021Время чтения ~ 4 мин.SQL 2596

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

Делается это с помощью ключевого слова WHERE, которое размещается сразу после FROM. Я думаю, что WHERE — наиболее часто используемая конструкция, которая по смыслу совпадает с программистским IF. С помощью WHERE можно задавать разнообразные условия для фильтрации данных.

В общем случае SQL будет строиться по такой схеме:

SELECT поля 
FROM таблица 
WHERE условия
ORDER BY порядок
LIMIT смещение, количество;

Такова последовательность команд в любом SQL-запросе SELECT. Чуть позже мы добавим ещё команды группировки.

Условия в WHERE будут знакомы любому программисту, поскольку здесь работают все те же правила: больше, меньше, равно, логические AND, OR, NOT и т.п.

SELECT * FROM firstTable WHERE id > 2 ORDER BY id;
 
id  name
--------
3   Саша
4   Вася

Условие id > 2 отфильтрует данные и оставит только те, где id больше 2. Можно комбинировать разные условия.

SELECT * FROM firstTable WHERE id > 1 AND id <= 3 ORDER BY name;
 
id  name
--------
2   Петя
2   Петя
3   Саша

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

Условия для текста

Для поиска по текстовым полям применяется два условия LIKE и GLOB (реже). Аргументом LIKE является регулярное выражение, где символ % указывает на любую последовательность символов, а _ указывает на одиночный символ.

SELECT DISTINCT name FROM firstTable WHERE name LIKE 'П%';
 
name
----
Петя

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

SELECT DISTINCT name FROM firstTable WHERE name LIKE '_а%';
 
name
----
Вася
Саша

Здесь важный момент в том, что поиск в LIKE регистрозависимый (точнее для строк юникода, куда входит кириллица). Эта особенность SQLite серьёзно ограничивает возможности регистронезависимого поиска. :-(

На сегодняшний день фактически нет полноценного решения этой проблемы. Остаётся надеяться, что команда разработчиков добавит эту возможность в будущих версиях СУБД.

В некоторых случаях вместо LIKE можно использовать команду GLOB. Она работает аналогично, только использует спецзамены как это принято для файлов. Например * указывает на любую последовательность, _ — одиночный символ. Здесь же можно задать диапазон символов. Например так мы сможем найти все имена начинающиеся на «П» и «п»;

SELECT DISTINCT name FROM firstTable WHERE name GLOB '[пП]*';

Диапазоны значений

В некоторых случаях удобней использовать условия IN и BETWEEN, с помощью которых можно задать диапазон значений. Это заменяет многочисленные условия AND/OR.

SELECT * FROM firstTable WHERE id IN (1, 4) ORDER BY id;
  
id  name
--------
1   Вася
4   Вася

В данном случае IN указывает список возможных значений поля.

Условие BETWEEN задаёт диапазон «от-до»:

SELECT * FROM firstTable WHERE id BETWEEN 2 AND 4 ORDER BY id;
   
id  name
--------
2   Петя
2   Петя
3   Саша
4   Вася

Здесь мы ищем записи, где id будет иметь значение между 2 и 4.

C помощью логической команды NOT можно инвертировать условие. Например здесь мы получаем все записи, вне диапазона 2 и 4:

SELECT * FROM firstTable WHERE id NOT BETWEEN 2 AND 4 ORDER BY id;
 
id  name
--------
1   Вася

Обновление данных

После того, как мы познакомились с WHERE, можно поговорить о команде обновления UPDATE. Чаще всего мы обновляем только одну запись. Именно поэтому используется условие WHERE, где мы указываем какие именно строки нужно обновить. Например у нас в таблице два Пети и два Васи. При этом Пети у нас с одним id. Давайте их исправим.

Общая структура запроса UPDATE такая:

UPDATE таблица 
SET поле = значение,
    поле = значение
WHERE условие;

Изменим второго Васю (id = 4) на Борю.

UPDATE firstTable 
SET name = 'Боря'
WHERE id = 4;
 
id  name
---------
1   Вася
2   Петя 
3   Саша
4   Боря
2   Петя

Теперь давайте изменим второго Петю. Но есть нюанс — у обоих одинаковый id, то есть когда мы укажем его в условии WHERE, то обновятся обе записи — база просто не сможет их различить. Это произошло из-за того, что поле id не является уникальным, а представляет собой произвольное число. Так мы создали таблицу. В будущем мы вернемся к этому вопросу, но для таких ситуаций SQLite предоставляет автоматически генерируемый уникальный номер каждой записи. Он называется ROWID и по сути представляет собой просто скрытое поле.

SELECT rowid, * FROM firstTable ORDER BY rowid;
 
rowid  id  name
--------------
1      1   Вася
2      2   Петя 
3      3   Саша
4      4   Боря
5      2   Петя

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

UPDATE firstTable 
SET
   id = 5, 
   name = 'Миша'
WHERE rowid = 5;
 
SELECT * FROM firstTable ORDER BY id;
 
id  name
---------
1   Вася
2   Петя 
3   Саша
4   Боря
5   Миша

Команда UPDATE достаточно проста для понимания, но как и INSERT требует соблюдения структуры таблицы.

Удаление с условием

Мы уже знаем команду DELETE, которая очищает таблицу. Но мы можем точно также использовать WHERE, для того, чтобы указать выборочные записи для удаления.

Например сделаем новую запись, а потом её удалим.

INSERT INTO firstTable VALUES (6, 'Антон'); -- добавили новую запись
 
id  name
---------
1   Вася
2   Петя 
3   Саша
4   Боря
5   Миша
6   Антон
 
DELETE FROM firstTable WHERE id = 6; -- удалили
 
id  name
---------
1   Вася
2   Петя 
3   Саша
4   Боря
5   Миша

Итого

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

Похожие записи