SQL
SQL задачи на собеседовании тестировщика
Тестировщику SQL нужен для проверки данных: найти дубли, пустые значения, потерянные связи, некорректные статусы и расхождения между интерфейсом и базой. На собеседовании важно показать аккуратность проверки
Хорошая SQL-практика строится не вокруг угадывания синтаксиса, а вокруг вопроса к данным. Сначала нужно понять, какие таблицы участвуют, какая связь между ними, что фильтруем, что группируем и какой результат можно проверить глазами
Таблицы для тренировки
В примерах будем опираться на четыре таблицы:
customers(id, name, city)orders(id, customer_id, total, created_at, status)products(id, title, category, price)order_items(order_id, product_id, quantity)
Если вы тренируетесь в онлайн-тренажере, не копируйте схему буквально. Сначала найдите похожие таблицы в своей задаче: кто покупает, что покупает, где сумма, где дата, где связь между таблицами
Как работать с задачами
Перед каждым запросом запишите ожидаемый результат словами. Например: показать заказы дороже 5000, найти клиентов без заказов, посчитать продажи по городам
После запуска не смотрите только на отсутствие ошибки. Проверьте количество строк, сортировку, пустые случаи и дубли. Именно на таких проверках становится видно, понимаете ли вы запрос
Задачи с решениями
Задача 1. Найти дубли клиентов по имени и городу
Покажите пары name и city, которые встречаются больше одного раза
Решение:
SELECT name, city, COUNT(*) AS rows_count
FROM customers
GROUP BY name, city
HAVING COUNT(*) > 1;
Проверка: добавьте двух клиентов с одинаковыми данными
Задача 2. Найти заказы без клиента
Покажите заказы, у которых нет связанного клиента
Решение:
SELECT o.id, o.customer_id
FROM orders o
LEFT JOIN customers c ON c.id = o.customer_id
WHERE c.id IS NULL;
Проверка: объясните, почему используется LEFT JOIN
Задача 3. Проверить отрицательные суммы
Найдите заказы с некорректной суммой
Решение:
SELECT id, total
FROM orders
WHERE total < 0;
Проверка: проверьте также сумму 0, если бизнес-правила ее запрещают
Задача 4. Проверить неизвестные статусы
Найдите заказы со статусом не из разрешенного списка
Решение:
SELECT id, status
FROM orders
WHERE status NOT IN ('new', 'paid', 'cancelled');
Проверка: добавьте статус с опечаткой и убедитесь, что запрос его ловит
Задача 5. Сверить сумму заказа с позициями
Сравните сумму заказа с суммой его строк
Решение:
SELECT
o.id,
o.total,
SUM(oi.quantity * p.price) AS calculated_total
FROM orders o
JOIN order_items oi ON oi.order_id = o.id
JOIN products p ON p.id = oi.product_id
GROUP BY o.id, o.total
HAVING o.total <> SUM(oi.quantity * p.price);
Проверка: проверьте заказ с несколькими позициями
Задача 6. Найти клиентов без заказов
Выведите клиентов, у которых нет записей в таблице заказов
Решение:
SELECT c.id, c.name
FROM customers c
LEFT JOIN orders o ON o.customer_id = c.id
WHERE o.id IS NULL;
Проверка: добавьте клиента без заказа и проверьте, что он появился в результате
По этой теме полезно отдельно посмотреть SQL тренажер: как практиковаться в запросах, чтобы расширить контекст и сравнить подходы
По этой теме полезно отдельно посмотреть SQL Academy тренажер: как практиковаться, чтобы расширить контекст и сравнить подходы
Как отвечать на собеседовании
Не ограничивайтесь фразой «я бы сделал SELECT». Покажите проверочную логику: какие данные считаются ошибочными, какой запрос их находит и как вы убедитесь, что запрос не дает ложные срабатывания
Как читать готовый запрос
Начинайте с FROM: откуда берутся данные. Потом смотрите JOIN, потому что именно там часто теряются строки или появляются дубли. После этого переходите к WHERE, GROUP BY, HAVING, SELECT и ORDER BY
Если запрос длинный, запускайте его слоями: сначала одна таблица, затем соединение, затем фильтр, затем группировка. Такой порядок быстрее показывает место ошибки
Типичные ошибки
- использовать
SELECT *, когда нужны конкретные поля - забывать условие соединения в
JOIN - фильтровать агрегаты через
WHERE, хотя нуженHAVING - не проверять клиентов или товары без связанных записей
- считать строки вместо уникальных значений
- не смотреть на
NULL
Почти любую SQL-задачу можно упростить до маленькой проверки. Если результат странный, временно уберите часть условий и посмотрите, на каком шаге данные изменились не так
План практики
- Напишите пять запросов
SELECTс разными полями - Добавьте фильтры
WHERE - Потренируйте
ORDER BYиLIMIT - Перейдите к
GROUP BYи агрегатам - Добавьте
JOIN - Проверьте
LEFT JOINи отсутствующие связи - Перепишите один длинный запрос в несколько понятных шагов
Тестировочный сценарий
Для тестировщика SQL часто начинается с вопроса: «Какие данные могут быть неправильными?» Не нужно сразу писать большой отчет. Составьте список рисков и под каждый риск маленький запрос
Примеры рисков:
- заказ ссылается на несуществующего клиента
- сумма заказа отрицательная
- статус написан с опечаткой
- у заказа нет товарных позиций
- итог заказа не совпадает с суммой позиций
Проверка заказов без позиций:
SELECT o.id
FROM orders o
LEFT JOIN order_items oi ON oi.order_id = o.id
WHERE oi.order_id IS NULL;
Как объяснить результат
Если запрос вернул строки, это не всегда баг. Возможно, такие данные разрешены бизнес-логикой. Поэтому хороший ответ тестировщика звучит так: «Я нашел подозрительные строки, дальше сверяю их с правилом: может ли существовать заказ без позиций в статусе new или это ошибка только для paid»
Финальная самопроверка
Перед тем как считать задачу решенной, проверьте четыре вещи. Первая — не потерялись ли строки при соединении таблиц. Если в условии важны клиенты без заказов или товары без продаж, обычный JOIN может скрыть нужные строки. Вторая — не появились ли дубли после соединения. Один заказ с несколькими позициями может размножить строки, и обычный COUNT(*) начнет считать не то
Третья проверка — границы фильтра. Если написано «от 5000», уточните, входит ли сама сумма 5000. Для этого есть разница между > и >=. Четвертая проверка — смысл итоговой строки. После GROUP BY одна строка результата должна соответствовать одной группе: клиенту, городу, дню, товару или категории
Мини-задание для закрепления: возьмите любой запрос из статьи и перепишите его в два варианта — сначала через обычный JOIN, потом через LEFT JOIN. Сравните количество строк и объясните, почему результат отличается. Это упражнение быстро показывает, понимаете ли вы связь между таблицами