Блог

SQL для QA инженера: JOIN, SELECT и проверка данных

SQL для QA: JOIN запросы и проверка данных

Тестировщик открыл баг: "При оформлении заказа отображается неправильная цена". Разработчик спрашивает: "А в базе какая цена?" И тут два варианта. Первый - QA идёт к разработчику и просит посмотреть. Второй - открывает терминал, пишет SELECT и за 10 секунд получает ответ.
SQL - это язык для работы с базами данных. Для QA инженера это инструмент проверки данных: правильно ли записался заказ, совпадает ли цена на фронте с ценой в базе, не потерялись ли данные при импорте. Без SQL тестировщик видит только интерфейс. С SQL - видит всю картину.
В этой статье разберём именно то, что нужно QA: SELECT, WHERE, JOIN и конкретные приёмы проверки данных. Без теории ради теории - только практика.

Базовые запросы: SELECT и WHERE

Всё начинается с SELECT. Это команда для получения данных из таблицы.
SELECT * FROM users;
Этот запрос вернёт все строки и все столбцы из таблицы users. Звёздочка (*) означает "все столбцы".
На практике все столбцы нужны редко. Выбирайте конкретные:
SELECT id, name, email FROM users;
WHERE добавляет фильтрацию:
SELECT id, name, email FROM users WHERE status = 'active';
Этот запрос вернёт только активных пользователей.
Операторы фильтрации, которые нужны каждый день:
= равно
!= или <> не равно
> < >= <= сравнение
BETWEEN x AND y диапазон
IN (a, b, c) одно из значений
LIKE '%текст%' поиск по части строки
IS NULL / IS NOT NULL проверка на пустое значение
Пример из реальной работы QA. Вам нужно проверить, что все заказы за последнюю неделю имеют статус:
SELECT id, status, created_at FROM orders
WHERE created_at >= '2026-02-21'
AND status NOT IN ('completed', 'cancelled');
Если запрос вернул строки - значит есть заказы в непонятном статусе. Это потенциальный баг.

ORDER BY и LIMIT: сортировка и ограничение

ORDER BY сортирует результат:
SELECT * FROM orders ORDER BY created_at DESC;
DESC - от новых к старым. ASC (по умолчанию) - от старых к новым.
LIMIT ограничивает количество строк:
SELECT * FROM orders ORDER BY created_at DESC LIMIT 10;
Последние 10 заказов. Полезно, когда в таблице миллионы строк и SELECT * повесит базу.
Комбинация ORDER BY + LIMIT - ваш основной инструмент для быстрых проверок: "Покажи последние 5 регистраций", "Покажи самый дорогой заказ".

GROUP BY и агрегатные функции

GROUP BY группирует строки для подсчёта статистики. Агрегатные функции работают с группами:
COUNT(*) - количество строк
SUM(column) - сумма
AVG(column) - среднее
MIN(column) - минимум
MAX(column) - максимум
Пример: сколько заказов в каждом статусе?
SELECT status, COUNT(*) as cnt
FROM orders
GROUP BY status;
Результат:
completed 1250
pending 43
cancelled 87
processing 12
Если вы видите 500 заказов в статусе "processing" при норме 10-15 - что-то сломалось.
HAVING фильтрует результаты после группировки:
SELECT user_id, COUNT(*) as order_count
FROM orders
GROUP BY user_id
HAVING COUNT(*) > 100;
Пользователи с более чем 100 заказами. Может быть тестовый аккаунт, а может - баг с дублированием.

JOIN: объединение таблиц

JOIN - самая важная тема для QA после SELECT. Данные в базе разложены по таблицам: пользователи отдельно, заказы отдельно, товары отдельно. Чтобы собрать полную картину, таблицы нужно объединить.
INNER JOIN - пересечение
Возвращает строки, которые есть в обеих таблицах:
SELECT u.name, o.id as order_id, o.total
FROM users u
INNER JOIN orders o ON u.id = o.user_id;
Покажет пользователей, у которых есть заказы. Пользователи без заказов и заказы без пользователей - не попадут.
LEFT JOIN - все из левой таблицы
Возвращает все строки из левой таблицы, даже если в правой нет совпадений:
SELECT u.name, o.id as order_id
FROM users u
LEFT JOIN orders o ON u.id = o.user_id;
Покажет всех пользователей. У тех, кто не делал заказов, в столбце order_id будет NULL.
Это мощный приём для QA. Хотите найти пользователей без заказов?
SELECT u.name, u.email
FROM users u
LEFT JOIN orders o ON u.id = o.user_id
WHERE o.id IS NULL;
Если среди них есть пользователи, зарегистрированные месяц назад и с подтверждённой оплатой - это баг: деньги списали, заказ не создался.
RIGHT JOIN и FULL JOIN
RIGHT JOIN - зеркало LEFT JOIN, все строки из правой таблицы. На практике используется редко: проще поменять таблицы местами и написать LEFT JOIN.
FULL JOIN - все строки из обеих таблиц. Полезен для поиска рассинхронизации: записи есть в одной системе, но нет в другой.

Практические запросы для QA

Вот конкретные запросы, которые QA используют каждый день:
Проверка дублей:
SELECT email, COUNT(*) as cnt
FROM users
GROUP BY email
HAVING COUNT(*) > 1;
Если email уникален - запрос ничего не вернёт. Если вернул строки - баг в валидации регистрации.
Проверка целостности данных:
SELECT o.id
FROM orders o
LEFT JOIN users u ON o.user_id = u.id
WHERE u.id IS NULL;
Заказы без пользователя. Если такие есть - нарушена целостность данных.
Сравнение сумм:
SELECT o.id, o.total,
SUM(oi.price * oi.quantity) as calculated_total
FROM orders o
JOIN order_items oi ON o.id = oi.order_id
GROUP BY o.id, o.total
HAVING o.total != SUM(oi.price * oi.quantity);
Находит заказы, где сумма в заголовке не совпадает с суммой позиций. Классический баг в интернет-магазинах.
Поиск аномалий по времени:
SELECT DATE(created_at) as day, COUNT(*) as registrations
FROM users
GROUP BY DATE(created_at)
ORDER BY registrations DESC
LIMIT 10;
Дни с аномально высокой регистрацией. Может быть маркетинговая акция, а может - бот-атака.
Проверка статусных переходов:
SELECT * FROM orders
WHERE status = 'delivered'
AND paid_at IS NULL;
Доставленные, но не оплаченные заказы. Если бизнес-логика требует оплату до доставки - это баг.

Частые ошибки новичков в SQL

SELECT * в продакшн-базе
Таблица с миллионом строк. SELECT * без WHERE и LIMIT - и база зависла на 5 минут. Всегда добавляйте LIMIT при первом запросе к незнакомой таблице.
Путаница WHERE и HAVING
WHERE фильтрует строки до группировки. HAVING - после. WHERE status = 'active' GROUP BY city - сначала отфильтрует активных, потом сгруппирует по городам. HAVING COUNT(*) > 10 - сначала сгруппирует, потом отфильтрует группы.
Забыли про NULL
WHERE status != 'cancelled' НЕ вернёт строки, где status = NULL. NULL - это не значение, а отсутствие значения. Правильно: WHERE status != 'cancelled' OR status IS NULL.
JOIN без понимания связей
Прежде чем писать JOIN, поймите связи между таблицами. Один пользователь - много заказов (один-ко-многим). Один заказ - много товаров (один-ко-многим через order_items). Неправильный JOIN даст дублирование строк или потерю данных.

Где практиковать SQL

Теория без практики в SQL бесполезна. Вот конкретные ресурсы:
- sql-ex.ru - задачи от простых к сложным, классика для подготовки к собеседованиям
- leetcode.com/problemset/database - SQL-задачи с проверкой
- pgexercises.com - интерактивные упражнения на PostgreSQL
- mode.com/sql-tutorial - туториал с реальными данными
Минимальная программа для QA: решите 30-40 задач на sql-ex.ru (разделы SELECT, JOIN, GROUP BY). Этого хватит для 90% рабочих ситуаций и собеседований.

Вопросы и ответы по SQL для QA

Какой SQL нужен тестировщику: MySQL, PostgreSQL или другой?
Синтаксис базовых запросов одинаков везде. SELECT, JOIN, WHERE, GROUP BY работают и в MySQL, и в PostgreSQL, и в MS SQL. Различия начинаются в продвинутых функциях: оконные функции, CTE, специфичные типы данных. Для старта язык значения не имеет.
Обязательно ли учить SQL для первой работы в QA?
Для Junior Manual QA - желательно, но не блокирует. Для Middle и выше - обязательно. На собеседованиях SQL спрашивают в 7 из 10 компаний. Базовый уровень осваивается за 2-3 недели ежедневных занятий по часу.
Можно ли случайно удалить данные в рабочей базе?
Да, если есть права на запись. Поэтому на проде QA обычно получает read-only доступ. На тестовых стендах - полный доступ. Золотое правило: перед DELETE или UPDATE всегда сначала запустите SELECT с тем же WHERE и убедитесь, что выбраны правильные строки.

SQL как ступень роста в QA

SQL отделяет начинающего тестировщика от уверенного. С SQL вы не зависите от разработчика при проверке данных, быстрее локализуете баги и можете аргументировать свои баг-репорты конкретными данными из базы.
Освоить базовый SQL для QA можно за 2-3 недели. Это одна из самых быстро окупаемых инвестиций в карьере тестировщика - и на собеседованиях, и в ежедневной работе.
Если хотите изучать SQL и другие инструменты QA с ментором, который объяснит на реальных примерах - у меня есть индивидуальное менторство. Разберём ваш уровень, составим план обучения и будем двигаться в вашем темпе.
Записаться на бесплатную консультацию:
2026-02-27 14:50