Ультимативный учебник по SQL

Интерактивная шпаргалка для тестировщиков: от основ до JOIN'ов и практических советов.

1. Что такое SQL?

SQL (Structured Query Language) — это язык структурированных запросов, который используется для общения с реляционными базами данных. С его помощью тестировщик может:

  • Проверять, корректно ли сохранились данные после действий в интерфейсе.
  • Создавать тестовые данные (например, новых пользователей или заказы).
  • Находить специфические данные для сложных тест-кейсов.
  • Удалять "мусорные" данные после прогона автотестов.

Структура запроса

Любой SQL-запрос состоит из "команд" или операторов. Наведите на них, чтобы узнать больше.

SELECT first_name, email FROM employees WHERE department_id = 1;

Порядок выполнения

Хотя мы пишем SELECT вначале, база данных выполняет операторы в другом, логическом порядке:

1 FROM
2 WHERE
3 GROUP BY
4 HAVING
5 SELECT
6 ORDER BY
7 LIMIT

2. Типы данных

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

  • INTEGER (INT): Целые числа (1, 100, -50).
  • VARCHAR(n): Текстовая строка переменной длины до n символов ('Иван'). Экономит место.
  • CHAR(n): Текстовая строка фиксированной длины n символов ('M', 'F'). Быстрее для полей с одинаковой длиной.
  • TEXT: Для хранения длинных текстов (описания товаров, статьи).
  • DECIMAL(p, s) / NUMERIC: Числа с фиксированной точностью (199.99). Идеальны для денег, чтобы избежать ошибок округления.
  • FLOAT / REAL: Числа с плавающей точкой. Используются для научных расчетов.
  • DATE: Дата ('2025-10-03').
  • TIMESTAMP / DATETIME: Дата и время ('2025-10-03 17:00:00'). TIMESTAMP часто хранит время в UTC.
  • BOOLEAN: Логические значения (true или false).
  • NULL: Специальное значение, означающее "нет данных" или "неприменимо". Не путать с пустой строкой '' или нулем 0.

3. Создание и управление (DDL & DML)

Это команды для работы со структурой базы (DDL - Data Definition Language) и манипулирования самими данными (DML - Data Manipulation Language). Для всех примеров ниже мы будем использовать тестовую таблицу employees.

Работа с базами данных

SHOW DATABASES: Показать все БД

QA-кейс: Убедиться, что вы подключились к правильному серверу и видите нужную тестовую базу данных.

SHOW DATABASES;

CREATE/DROP DATABASE: Создать/Удалить БД

QA-кейс: Создание полностью изолированной базы данных для прогона набора автотестов с последующим её удалением.

-- Создаем новую БД CREATE DATABASE test_automation_db;

-- Удаляем БД после тестов DROP DATABASE test_automation_db;

USE: Выбрать БД для работы

QA-кейс: Перед выполнением любых запросов к таблицам, нужно "активировать" базу данных, с которой вы будете работать.

USE main_project_db;

Работа с таблицами

CREATE TABLE: Создать таблицу

QA-кейс: Создание временной таблицы для хранения промежуточных результатов сложного теста.

CREATE TABLE users (
    id INT AUTO_INCREMENT PRIMARY KEY,
    username VARCHAR(50) NOT NULL,
    email VARCHAR(100) UNIQUE,
    birthdate DATE
);

INSERT INTO: Добавить данные

QA-кейс: Создать нового тестового пользователя перед проверкой логина.

INSERT INTO employees (first_name, last_name, email, department_id, salary)
VALUES ('Тест', 'Тестов', 'test@example.com', 2, 55000.00);

UPDATE: Изменить данные

QA-кейс: Изменить статус заказа на "Доставлен" для проверки отображения в личном кабинете.

UPDATE employees SET email = 'new_email@example.com' WHERE id = 2;

DELETE: Удалить данные

QA-кейс: "Почистить" базу данных, удалив тестового пользователя, созданного во время теста.

DELETE FROM employees WHERE email = 'test@example.com';

ALTER TABLE: Изменить структуру таблицы

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

-- Добавление нового столбца ALTER TABLE employees ADD COLUMN phone_number VARCHAR(20);

-- Изменение типа столбца ALTER TABLE employees MODIFY COLUMN phone_number INT;

-- Удаление столбца ALTER TABLE employees DROP COLUMN birthdate;

4. Выборка данных (SELECT)

SELECT — самая частая команда в работе тестировщика. Она позволяет "доставать" нужные данные для проверки. Для всех примеров будем использовать эту таблицу:

Таблица: `employees`
idfirst_namelast_namedepartment_idsalary
1ИванПетров170000.00
2АннаСидорова265000.00
3СергейИванов172000.00
4ЕленаСмирнова380000.00
5ДмитрийКузнецов260000.00

SELECT *: Выбрать все столбцы

QA-кейс: Посмотреть всю информацию о сотрудниках, чтобы убедиться, что тестовые данные на месте.

SELECT * FROM employees;
Результат:
idfirst_namelast_namedepartment_idsalary
1ИванПетров170000.00
2АннаСидорова265000.00
3СергейИванов172000.00
4ЕленаСмирнова380000.00
5ДмитрийКузнецов260000.00

SELECT DISTINCT: Уникальные значения

QA-кейс: Получить список всех уникальных ID отделов, в которых есть сотрудники, для проверки фильтра в UI.

SELECT DISTINCT department_id FROM employees;
Результат:
department_id
1
2
3

LIMIT: Ограничить количество записей

QA-кейс: Проверить пагинацию. Запросить первые 3 записи для первой страницы списка сотрудников.

SELECT * FROM employees LIMIT 3;
Результат:
idfirst_namelast_namedepartment_idsalary
1ИванПетров170000.00
2АннаСидорова265000.00
3СергейИванов172000.00

AS: Переименовать столбец

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

SELECT first_name AS "Имя", last_name AS "Фамилия" FROM employees;
Результат:
ИмяФамилия
ИванПетров
АннаСидорова
СергейИванов
ЕленаСмирнова
ДмитрийКузнецов

WHERE: Фильтрация по условию

QA-кейс: Найти всех сотрудников из отдела с ID=1.

SELECT * FROM employees WHERE department_id = 1;
Результат:
idfirst_namelast_namedepartment_idsalary
1ИванПетров170000.00
3СергейИванов172000.00

WHERE ... AND / OR: Комбинирование условий

QA-кейс (AND): Найти сотрудников из отдела 1, которые зарабатывают больше 71000.

SELECT * FROM employees WHERE department_id = 1 AND salary > 71000;
Результат (AND):
idfirst_namelast_namedepartment_idsalary
3СергейИванов172000.00

QA-кейс (OR): Найти всех сотрудников из отдела 1 или отдела 3.

SELECT * FROM employees WHERE department_id = 1 OR department_id = 3;
Результат (OR):
idfirst_namelast_namedepartment_idsalary
1ИванПетров170000.00
3СергейИванов172000.00
4ЕленаСмирнова380000.00

LIKE: Фильтр по шаблону

QA-кейс: Найти всех сотрудников, чья фамилия заканчивается на "ов".

-- % означает любое количество символов SELECT * FROM employees WHERE last_name LIKE '%ов';
Результат:
idfirst_namelast_namedepartment_idsalary
1ИванПетров170000.00
3СергейИванов172000.00

QA-кейс: Найти всех, чье имя состоит из 4 букв и начинается на "Ива".

-- _ означает ровно один любой символ SELECT * FROM employees WHERE first_name LIKE 'Ива_';
Результат:
idfirst_namelast_namedepartment_idsalary
1ИванПетров170000.00

BETWEEN / IN / NOT: Диапазоны, списки и отрицание

BETWEEN: Найти сотрудников с зарплатой от 65000 до 75000 включительно.

SELECT * FROM employees WHERE salary BETWEEN 65000.00 AND 75000.00;

IN: Найти сотрудников из отделов 2 и 3.

SELECT * FROM employees WHERE department_id IN (2, 3);

NOT: Найти всех сотрудников НЕ из отдела 1.

SELECT * FROM employees WHERE NOT department_id = 1;

ORDER BY: Сортировка результатов

QA-кейс: Проверить правильность сортировки по зарплате в UI. Сначала по убыванию (DESC), потом по возрастанию (ASC).

-- Сортировка по убыванию SELECT * FROM employees ORDER BY salary DESC;
Результат (DESC):
idfirst_namelast_namedepartment_idsalary
4ЕленаСмирнова380000.00
3СергейИванов172000.00
1ИванПетров170000.00
2АннаСидорова265000.00
5ДмитрийКузнецов260000.00

5. Агрегация и Группировка

Агрегатные функции выполняют вычисления на наборе значений и возвращают одно-единственное значение. Они почти всегда используются с GROUP BY.

COUNT: Подсчет количества

QA-кейс: После создания 5 пользователей через API, проверить, что в таблице `employees` действительно стало на 5 записей больше.

SELECT COUNT(*) AS total_employees FROM employees;
Результат:
total_employees
5

MIN / MAX / AVG / SUM: Минимум, максимум, среднее, сумма

QA-кейс: Проверить статистический виджет на дашборде, который должен показывать минимальную, максимальную и среднюю зарплату по компании.

SELECT MIN(salary) AS min_salary,
    MAX(salary) AS max_salary,
    AVG(salary) AS avg_salary,
    SUM(salary) AS total_salary_fund
FROM employees;
Результат:
min_salarymax_salaryavg_salarytotal_salary_fund
60000.0080000.0069400.00347000.00

GROUP BY и HAVING: Группировка и фильтрация групп

QA-кейс: Найти отделы, в которых работает более одного сотрудника, чтобы проверить логику начисления бонусов руководителям этих отделов.

SELECT department_id,
    COUNT(id) AS employee_count
FROM employees GROUP BY department_id HAVING COUNT(id) > 1;
Результат:
department_idemployee_count
12
22

Ключевое отличие: WHERE vs HAVING

  • WHERE фильтрует строки до того, как они будут сгруппированы.
  • HAVING фильтрует группы после того, как они были созданы с помощью GROUP BY.

6. Объединение результатов

Операторы UNION и UNION ALL объединяют результаты двух или более SELECT запросов в один набор данных.

Правила применения UNION:

  • Каждый SELECT запрос в UNION должен иметь одинаковое количество столбцов.
  • Столбцы также должны иметь совместимые типы данных (например, нельзя объединять число со строкой).
  • Столбцы в каждом SELECT запросе должны быть в одинаковом порядке.
  • Названия столбцов в итоговом результате берутся из первого SELECT запроса.

UNION: Объединение с удалением дубликатов

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

SELECT email FROM employees UNION SELECT email FROM customers;

UNION ALL: Объединение всех записей

QA-кейс: Собрать полный лог всех действий (входы и выходы) из двух разных таблиц для анализа активности пользователя, сохраняя хронологию и все события.

SELECT user_id,
    action,
    timestamp FROM login_logs UNION ALL SELECT user_id,
    action,
    timestamp FROM action_logs;

7. JOIN'ы

JOIN'ы позволяют объединять строки из двух или более таблиц по связанным столбцам (ключам). Это одна из самых мощных концепций в SQL.

Таблицы для примеров:

Таблица: `users`
idname
1Иван
2Анна
3Петр
Таблица: `orders`
order_iduser_iditem
1011Книга
1022Телефон
1031Мышь
1044Лампа

INNER JOIN: Только совпадения

Возвращает только те строки, для которых есть совпадение в обеих таблицах. Пользователи без заказов (Петр) и заказы без пользователей (заказ 104) не попадут в результат.

SELECT u.name, o.item FROM users u
INNER JOIN orders o ON u.id = o.user_id;
Результат:
nameitem
ИванКнига
АннаТелефон
ИванМышь

LEFT JOIN: Все из левой таблицы

Возвращает все строки из левой таблицы (users) и совпавшие строки из правой (orders). Если для пользователя нет заказа (как для Петра), в столбцах из правой таблицы будет NULL.

SELECT u.name, o.item FROM users u
LEFT JOIN orders o ON u.id = o.user_id;
Результат:
nameitem
ИванКнига
ИванМышь
АннаТелефон
ПетрNULL

RIGHT JOIN: Все из правой таблицы

Возвращает все строки из правой таблицы (orders) и совпавшие строки из левой (users). Если для заказа нет пользователя (как для заказа 104), в столбцах из левой таблицы будет NULL.

SELECT u.name, o.item FROM users u
RIGHT JOIN orders o ON u.id = o.user_id;
Результат:
nameitem
ИванКнига
АннаТелефон
ИванМышь
NULLЛампа

8. Продвинутые темы

Транзакции

Транзакция — это последовательность операций, которая выполняется как единое целое по принципу "всё или ничего". Либо все операции успешны и сохраняются (COMMIT), либо все отменяются (ROLLBACK). Это гарантирует целостность данных.

START TRANSACTION;
-- Снимаем 100$ со счета A UPDATE Accounts SET balance = balance - 100 WHERE id = 'A';
-- Добавляем 100$ на счет B UPDATE Accounts SET balance = balance + 100 WHERE id = 'B';
-- Если обе операции успешны, сохраняем изменения COMMIT;

Зачем тестировщику дампы?

Дамп (dump) — это файл, содержащий структуру и данные базы данных в виде набора SQL-команд. QA-инженер использует дампы для:

  • Воспроизведения багов. Если на продакшене произошел баг, связанный с данными, разработчики могут прислать "обезличенный" дамп (без персональных данных), чтобы QA мог локально развернуть копию БД и точно воспроизвести проблему.
  • Настройки тестового окружения. Вместо ручного создания сотен тестовых записей, можно один раз развернуть готовый дамп с преднастроенными данными, что экономит массу времени.
  • Тестирования миграций. Чтобы проверить, что скрипт обновления структуры БД (миграция) работает корректно, QA может взять дамп старой версии, "накатить" на него миграцию и проверить, что все данные на месте и структура обновилась правильно.
  • Анализа данных от клиента. Иногда клиенты присылают дампы своих данных для анализа сложных проблем. QA может развернуть их на тестовом стенде и исследовать, не затрагивая "боевую" систему клиента.

9. Практический SQL для QA

SQL — это не теория, а ежедневный инструмент тестировщика. Вот как выглядит типичный рабочий процесс.

Шаг 0: Получение доступа

Прежде чем начать, вам понадобятся доступы к базе данных. Запросите у системного администратора или тимлида следующие данные:

  • Хост (Host/Server): Адрес сервера, где находится БД (например, db-test.myproject.com).
  • Порт (Port): Обычно 5432 для PostgreSQL или 3306 для MySQL.
  • Имя базы данных (Database Name): Например, myproject_test_db.
  • Имя пользователя (Username) и Пароль (Password).
  • Клиент для подключения: Уточните, какой программой пользоваться (DBeaver, DataGrip, pgAdmin).

Пример: Тестирование регистрации нового пользователя

Представим, что мы тестируем форму регистрации на сайте.

  1. Подготовка: Убедимся, что пользователя с нашим тестовым email еще не существует.
    SELECT * FROM users WHERE email = 'qa-test-user@example.com';

    Ожидаемый результат: запрос вернет 0 строк.

  2. Действие: Идем в интерфейс нашего приложения и регистрируем нового пользователя с данными: Имя - "Тестовый", Фамилия - "Пользователь", Email - "qa-test-user@example.com".
  3. Проверка: Теперь ищем этого пользователя в базе данных.
    SELECT * FROM users WHERE email = 'qa-test-user@example.com';

    Ожидаемый результат: запрос вернет 1 строку.

  4. Валидация: Внимательно проверяем все поля в полученной строке:
    • first_name должен быть 'Тестовый'.
    • last_name должен быть 'Пользователь'.
    • is_active должен быть 'true' (или 1), если пользователь сразу активен.
    • created_at должен быть примерно равен текущему времени.
  5. Очистка: Чтобы не оставлять тестовые данные в базе и иметь возможность повторить тест, удаляем созданную запись.
    DELETE FROM users WHERE email = 'qa-test-user@example.com';

    Этот шаг особенно важен для автотестов.