Готовые SQL-тесты из интернета — не лучшее решение. Кандидаты их знают, ответы можно найти в поисковике. Собственный тест под задачи компании — более честная проверка и лучший предиктор успеха в работе.
Шаг 1: Определите, что важно именно у вас
Начните с разговора с командой: какие SQL-задачи встречаются в ежедневной работе?
Составьте список из 10–15 реальных задач (анонимизированных), например:
- Построить retention-отчёт по когортам
- Найти клиентов с аномально высокой частотой покупок
- Рассчитать долю каждого продукта в категории
Из этих задач получатся лучшие тестовые задания — они напрямую предсказывают успех в роли.
Шаг 2: Разработайте тестовый датасет
Хороший тестовый датасет — это ключ к качественному тесту. Требования:
Размер: 100–1000 строк в каждой таблице — достаточно для работы, но не так много, чтобы запросы выполнялись долго.
Структура: похожа на реальные рабочие таблицы компании, но анонимизирована.
Данные: содержат edge cases — NULL-значения, дубликаты, граничные даты, нулевые суммы.
Пример схемы для e-commerce компании:
-- Используйте реальные названия из вашей индустрии
CREATE TABLE customers (
id SERIAL PRIMARY KEY,
name VARCHAR(100),
email VARCHAR(200),
city VARCHAR(100),
registered_at TIMESTAMP,
segment VARCHAR(20) -- 'retail', 'wholesale', NULL
);
CREATE TABLE orders (
id SERIAL PRIMARY KEY,
customer_id INT REFERENCES customers(id),
amount NUMERIC(10, 2),
status VARCHAR(20), -- 'completed', 'cancelled', 'refunded'
created_at TIMESTAMP
);
CREATE TABLE order_items (
id SERIAL PRIMARY KEY,
order_id INT REFERENCES orders(id),
product_id INT,
quantity INT,
unit_price NUMERIC(10, 2)
);
Шаг 3: Напишите задания по уровням
Junior-задания (40% теста)
Задания должны проверять базу: SELECT, WHERE, JOIN, GROUP BY. Кандидат, прошедший базовый курс SQL, должен с ними справляться.
-- Пример Junior-задания с вашими данными:
-- "Найдите топ-3 города по числу зарегистрированных клиентов"
SELECT city, COUNT(*) AS customer_count
FROM customers
GROUP BY city
ORDER BY customer_count DESC
LIMIT 3;
Middle-задания (40% теста)
Оконные функции, CTE, сложные JOIN:
-- "Для каждого клиента найдите номер его заказа по счёту и
-- разницу суммы с предыдущим заказом"
SELECT
customer_id,
id AS order_id,
amount,
ROW_NUMBER() OVER (PARTITION BY customer_id ORDER BY created_at) AS order_num,
amount - LAG(amount) OVER (PARTITION BY customer_id ORDER BY created_at) AS diff_from_prev
FROM orders
WHERE status = 'completed';
Senior-задания (20% теста)
Оптимизация, сложная аналитика, специфика СУБД:
-- "Найдите клиентов, которые сделали заказ в каждом из 3 последних месяцев"
WITH recent_months AS (
SELECT DISTINCT DATE_TRUNC('month', created_at) AS month
FROM orders
WHERE created_at >= DATE_TRUNC('month', CURRENT_DATE) - INTERVAL '2 months'
),
active_customers AS (
SELECT customer_id, DATE_TRUNC('month', created_at) AS month
FROM orders
WHERE status = 'completed'
GROUP BY customer_id, DATE_TRUNC('month', created_at)
)
SELECT ac.customer_id
FROM active_customers ac
JOIN recent_months rm ON rm.month = ac.month
GROUP BY ac.customer_id
HAVING COUNT(DISTINCT ac.month) = (SELECT COUNT(*) FROM recent_months);
Шаг 4: Напишите эталонные решения
Для каждой задачи напишите эталонный запрос и зафиксируйте ожидаемый результат. Это основа автоматической проверки.
Важно: у одной задачи может быть несколько правильных решений. Автопроверка должна сравнивать результирующий набор данных, а не текст запроса.
Шаг 5: Определите критерии оценки
Проходной балл зависит от уровня позиции:
| Позиция | Junior-задачи | Middle-задачи | Senior-задачи | Проходной балл |
|---|---|---|---|---|
| Junior | ≥ 70% | — | — | 70% от Junior-части |
| Middle | ≥ 90% | ≥ 60% | — | Взвешенный ≥ 70% |
| Senior | 100% | ≥ 80% | ≥ 50% | Взвешенный ≥ 75% |
Шаг 6: Пилотное тестирование
Перед запуском теста прогоните его на нескольких сотрудниках вашей компании:
- Новый сотрудник уровня Junior — должен набрать около 70%
- Опытный Middle — должен набрать 85%+
- Senior из команды — должен решить всё
Если результаты не соответствуют ожиданиям — пересмотрите задания или пороги.
Шаг 7: Запустите и соберите обратную связь
После первых 20–30 прохождений проведите анализ:
-- Найдите задачи с аномально низким или высоким процентом решения
SELECT
task_id,
COUNT(*) AS total,
ROUND(100.0 * SUM(CASE WHEN is_correct THEN 1 END) / COUNT(*), 1) AS solve_rate
FROM task_responses
GROUP BY task_id
HAVING COUNT(*) >= 10
ORDER BY solve_rate;
Задачи с solve_rate < 15% — слишком сложные. С solve_rate > 95% — слишком лёгкие.
Типичные ошибки при создании теста
- Задачи без контекста: «Найдите всех Иванов» — непонятно, зачем
- Слишком большие таблицы: кандидат ждёт 30 секунд выполнения запроса
- Нет NULL в данных: реальные данные всегда содержат NULL, тест должен тоже
- Один правильный ответ: хороший тест допускает несколько подходов к решению
Для быстрого старта используйте готовую платформу — SQLlab.ru позволяет отправить кандидатам ссылку на готовый тест с реальной базой данных.