Урок по треку SQL и базы данных 6 мин

SELECT и фильтрация за 6 минут

Порядок выполнения запроса, WHERE, NULL, сортировка и пагинация.

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

Логический порядок

Пишем мы в одном порядке, а база «думает» в другом:

SELECT   name, price * 1.2 AS with_vat   -- 5
FROM     products                          -- 1
WHERE    price > 100                       -- 2
GROUP BY ...                               -- 3
HAVING   ...                               -- 4
ORDER BY with_vat DESC                     -- 6
LIMIT    10 OFFSET 20;                     -- 7

FROM → WHERE → GROUP BY → HAVING → SELECT → DISTINCT → ORDER BY → LIMIT/OFFSET.

Отсюда главное следствие: псевдоним из SELECT нельзя использовать в WHERE (на шаге WHERE его ещё нет), а в ORDER BY можно.

SELECT price * 1.2 AS with_vat FROM products WHERE with_vat > 100;  -- ошибка
SELECT price * 1.2 AS with_vat FROM products ORDER BY with_vat;      -- ок

WHERE и операторы

  • Сравнения: =, <> (или !=), <, >=.
  • Диапазон: price BETWEEN 100 AND 200 включает обе границы.
  • Список: city IN ('Москва', 'Казань').
  • Шаблон: name LIKE 'Ан%' (% любая строка, _ один символ). В PostgreSQL ILIKE без учёта регистра.
  • Логика: AND сильнее OR. a OR b AND c это a OR (b AND c). Ставьте скобки.

NULL: трёхзначная логика

NULL значит «неизвестно». Любое сравнение с NULL даёт не true и не false, а NULL (unknown). WHERE пропускает только строки, где условие true.

SELECT * FROM customers WHERE email = NULL;   -- всегда 0 строк
SELECT * FROM customers WHERE email IS NULL;  -- правильно

Ловушки:

  • WHERE city <> 'Москва' не вернёт строки с city IS NULL.
  • x NOT IN (1, 2, NULL) никогда не бывает true: результат пустой.
  • IS DISTINCT FROM сравнивает с учётом NULL: NULL IS DISTINCT FROM NULL это false.
  • COALESCE(email, 'нет') подставляет значение вместо NULL.

Сортировка

ORDER BY price DESC, id сортирует по цене по убыванию, при равной цене по id. Без ORDER BY порядок строк не гарантирован, даже если «всегда приходило по порядку».

В PostgreSQL NULL при ASC идут в конце, при DESC в начале. Управлять: ORDER BY email NULLS LAST.

DISTINCT

SELECT DISTINCT city FROM customers убирает дубли по всему набору выбранных колонок. NULL считаются одинаковыми, поэтому в результате будет один NULL. В PostgreSQL есть DISTINCT ON (col): первая строка в каждой группе по ORDER BY.

Пагинация

LIMIT 20 OFFSET 40 пропускает 40 строк и отдаёт 20. Без ORDER BY страницы могут пересекаться. На больших OFFSET база всё равно читает и выбрасывает все пропущенные строки, поэтому для глубоких страниц используют keyset-пагинацию:

SELECT * FROM orders WHERE id > 1040 ORDER BY id LIMIT 20;

CASE

Условие внутри выражения:

SELECT title,
       CASE WHEN price >= 1000 THEN 'дорого' ELSE 'нормально' END AS level
FROM products;

Частые ошибки

  • = NULL вместо IS NULL.
  • Псевдоним из SELECT в WHERE.
  • OR без скобок рядом с AND.
  • Уверенность, что без ORDER BY порядок стабилен.
  • NOT IN по подзапросу, где может быть NULL.

Что спросят на собесе

  • В каком порядке выполняются части SELECT и почему алиас нельзя в WHERE.
  • Как работает NULL в сравнениях и чем IS NULL отличается от = NULL.
  • Что вернёт NOT IN со списком, где есть NULL.
  • Чем плох большой OFFSET и что вместо него.
  • Гарантирован ли порядок строк без ORDER BY.

Закрепите за 5 минут

После урока в тренажёре 3-5 проверочных вопросов, дальше модуль уходит в повторения.