Глеб Зайцев
Качество каталога в SQL. 18 задач для карточек

Перед первой задачей

Почему каталог надо проверять запросами

Когда товаров становится много, ручной просмотр карточек быстро перестаёт работать.

SQL помогает найти пустые поля, дубли, странные цены, нулевые остатки и слабые описания до того, как они съедят показы и конверсию.

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

Граница применимости

Техническая проверка не гарантирует продажи, но убирает очевидные причины провала карточки.

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

Все примеры учебные и работают в SQLite без внешних файлов.

Маршрут по задачам

1. Найти товары без названия

2. Найти дубли SKU

3. Проверить товары без категории

4. Найти подозрительно короткие описания

5. Проверить отсутствие изображений

6. Найти карточки с малым числом изображений

7. Найти цены вне диапазона

8. Проверить нулевой остаток

9. Поймать одинаковые названия у разных SKU

10. Проверить пустые теги

11. Найти слишком длинные названия

12. Проверить конфликт цены и скидки

13. Проверить дубли изображений

14. Проверить товары без автора

15. Найти карточки с одинаковым описанием

16. Проверить длину артикула

17. Собрать общий счётчик проблем

18. Отобрать карточки без проблем

Практические задачи

Задача 1. Найти товары без названия

Рабочий вопрос

Нужно поймать карточки, где название пустое или состоит только из пробелов.

Данные

CREATE TABLE products(sku TEXT, title TEXT);

INSERT INTO products VALUES ('A1','Планер'),('B2',''),('C3',' ');

Запрос

SELECT sku

FROM products

WHERE trim(title) = ''

ORDER BY sku;

Ожидаемый результат

[["B2"], ["C3"]]

Почему работает

trim убирает пробелы по краям, после чего пустое название становится пустой строкой.

Запрос сделан на маленькой синтетической таблице, поэтому ответ можно проверить глазами и повторить в SQLite.

Явный ORDER BY или отдельная агрегация фиксируют смысл результата, а не оставляют его на случайный порядок строк.

Где легко ошибиться

Проверка title IS NULL нужна отдельно, если в данных возможны NULL, а не только пустые строки.

Самостоятельная проверка

Какие SKU проблемные? Объясните ответ по исходным строкам и условию запроса.

Ответ: B2 и C3. Это следует из исходных строк и условия запроса.

Задача 2. Найти дубли SKU

Рабочий вопрос

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

Данные

CREATE TABLE products(sku TEXT, title TEXT);

INSERT INTO products VALUES ('A1','Планер'),('A1','Планер v2'),('B2','Курс');

Запрос

SELECT sku, COUNT(*) AS rows_count

FROM products

GROUP BY sku

HAVING COUNT(*) > 1

ORDER BY sku;

Ожидаемый результат

[["A1", 2]]

Почему работает

GROUP BY sku собирает строки одного артикула, а HAVING оставляет повторяющиеся.

Запрос сделан на маленькой синтетической таблице, поэтому ответ можно проверить глазами и повторить в SQLite.

Явный ORDER BY или отдельная агрегация фиксируют смысл результата, а не оставляют его на случайный порядок строк.

Где легко ошибиться

DISTINCT sku скрыл бы проблему, потому что показал бы чистый список без числа дублей.

Самостоятельная проверка

Какой SKU повторяется? Объясните ответ по исходным строкам и условию запроса.

Ответ: A1. Это следует из исходных строк и условия запроса.

Задача 3. Проверить товары без категории

Рабочий вопрос

Нужно найти карточки, где категория не заполнена и товар может плохо классифицироваться.

Данные

CREATE TABLE products(sku TEXT, category TEXT);

INSERT INTO products VALUES ('A1','Книги'),('B2',NULL),('C3','');

Запрос

SELECT sku

FROM products

WHERE category IS NULL OR trim(category) = ''

ORDER BY sku;

Ожидаемый результат

[["B2"], ["C3"]]

Почему работает

Условие проверяет и NULL, и пустую строку после trim.

Запрос сделан на маленькой синтетической таблице, поэтому ответ можно проверить глазами и повторить в SQLite.

Явный ORDER BY или отдельная агрегация фиксируют смысл результата, а не оставляют его на случайный порядок строк.

Где легко ошибиться

NULL и пустая строка похожи в интерфейсе, но в SQL это разные состояния.

Самостоятельная проверка

Какие SKU без категории? Объясните ответ по исходным строкам и условию запроса.