Основы выборки: SELECT, фильтрация и сортировка

WHERE: фильтрация строк

Содержание курса

LIKE, IS NULL и IS NOT NULL: шаблонный и NULL-поиск

LIKE нужен, когда точное значение строки неизвестно, но известна её часть или структура. Шаблон содержит обычные символы и два специальных метасимвола.

% заменяет любое количество символов — в том числе ноль:

SELECT title
FROM products
WHERE title LIKE 'Но%';

Этот запрос найдёт «Ноутбук», «Носитель», «Но» и любую другую строку, начинающуюся на «Но».

_ заменяет ровно один символ:

SELECT title
FROM products
WHERE title LIKE '_ышь';

Шаблон _ышь соответствует строкам из четырёх символов, где последние три — «ышь». «Мышь» подходит, «Камышь» — нет (лишний символ). Именно фиксированная длина отличает _ от %.

NOT LIKE инвертирует: вернёт строки, не соответствующие шаблону.

Теперь о NULL. NULL — это не пустая строка и не ноль; это отсутствие значения как такового. Попытка сравнить с ним через = или <> не даёт ни TRUE, ни FALSE:

-- Этот запрос вернёт 0 строк, даже если NULL-строки есть
SELECT * FROM products WHERE price = NULL;

Выражение price = NULL вычисляется в NULL (неизвестно), а не в TRUE. WHERE пропускает только TRUE — значит, ни одна строка не пройдёт фильтр. Это не баг и не ошибка синтаксиса; движок честно выполнит запрос и честно вернёт пустой результат.

Для работы с NULL есть специальный синтаксис:

SELECT title, price
FROM products
WHERE price IS NULL;
SELECT title, price
FROM products
WHERE price IS NOT NULL;

IS NULL — это не оператор сравнения, а отдельная конструкция языка, которая явно проверяет отсутствие значения. Она всегда возвращает TRUE или FALSE, никогда NULL. Поэтому именно она корректно отбирает строки с незаполненными полями.

Практическое правило: если столбец может хранить NULL (а большинство столбцов могут, если нет ограничения NOT NULL), условия = NULL и <> NULL нужно заменять на IS NULL и IS NOT NULL — иначе фильтр молча пропустит все такие строки.

Проверим WHERE с пустым значением

В таблице три заказа: с известной суммой 100, с неизвестной суммой NULL и с нулевой суммой. NULL обозначает отсутствие значения, а не число 0. Проверим фильтры на SQLite в памяти. Python нужен только как простой способ запустить SQL без отдельного сервера.

import sqlite3
with sqlite3.connect(":memory:") as db:
    db.execute("CREATE TABLE orders (id INTEGER, amount INTEGER)")
    db.executemany("INSERT INTO orders VALUES (?, ?)", [(1,100),(2,None),(3,0)])
    known = db.execute("SELECT id FROM orders WHERE amount > 0 ORDER BY id").fetchall()
    missing = db.execute("SELECT id FROM orders WHERE amount IS NULL").fetchall()
    wrong = db.execute("SELECT id FROM orders WHERE amount = NULL").fetchall()
    assert known == [(1,)] and missing == [(2,)] and wrong == []
    print(known, missing, wrong)

Сравнение = NULL не возвращает строку с пропуском. В WHERE остаются только строки, для которых условие истинно. Для самопроверки найдите строки с суммой 0 и сравните результат с IS NULL. При переносе запросов в другой диалект сохраняйте смысл NULL и отдельно проверяйте специфичные функции.

Продолжите разбор: GROUP BY и HAVING.

Начать заново?

Помощник начнёт новый диалог по этой задаче. Текущая переписка останется в истории до конца срока хранения.

О переписке

Можно приложить до трёх фото PNG, JPEG или WebP по 5 МБ.

Переписка и фото хранятся 90 дней после последнего принятого сообщения. Преподаватель получит доступ к диалогу, когда вы попросите его помочь.

Проверка решения остаётся отдельным действием.