Работал ли с оконными функциями (Window Functions) в SQL?

«Работал ли с оконными функциями (Window Functions) в SQL?» — вопрос из категории Базы данных и SQL, который задают на 24% собеседований AQA / Automation. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Да, использовал оконные функции для написания сложных проверок и анализа данных в ходе тестирования.

Применение в QA:

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

    -- Получаем историю статусов и проверяем их последовательность
    SELECT 
        order_id,
        status,
        changed_at,
        LAG(status) OVER (PARTITION BY order_id ORDER BY changed_at) AS previous_status,
        CASE 
            WHEN status = 'NEW' AND LAG(status) OVER (PARTITION BY order_id ORDER BY changed_at) IS NULL THEN 'OK'
            WHEN status = 'PROCESSING' AND LAG(status) OVER (PARTITION BY order_id ORDER BY changed_at) = 'NEW' THEN 'OK'
            ELSE 'WRONG_SEQUENCE'
        END AS status_transition_check
    FROM order_status_history
    WHERE order_id IN (SELECT id FROM test_orders);
  2. Поиск дубликатов или аномалий в тестовых данных: Проверка, что для одного пользователя нет двух активных сессий одновременно.

    -- Находим сессии, которые перекрываются по времени у одного пользователя
    WITH session_intervals AS (
        SELECT 
            user_id,
            session_id,
            login_time,
            logout_time,
            LEAD(login_time) OVER (PARTITION BY user_id ORDER BY login_time) AS next_login_time
        FROM user_sessions
    )
    SELECT * 
    FROM session_intervals 
    WHERE logout_time > next_login_time; -- Перекрытие обнаружено
  3. Агрегация внутри групп для составления отчетов по тестовым прогонам: Например, анализ результатов тестов по фича-веткам.

    -- Анализ стабильности тестов в разных ветках
    SELECT 
        branch_name,
        test_class,
        test_name,
        execution_date,
        result,
        AVG(CASE WHEN result = 'PASS' THEN 1.0 ELSE 0.0 END) 
            OVER (PARTITION BY branch_name, test_class) AS pass_rate_per_class,
        COUNT(*) 
            OVER (PARTITION BY branch_name, test_name ORDER BY execution_date 
                  ROWS BETWEEN 4 PRECEDING AND CURRENT ROW) AS runs_last_5_days
    FROM test_execution_results
    ORDER BY branch_name, test_class, execution_date DESC;

Оконные функции (ROW_NUMBER, RANK, LAG, LEAD, агрегаты с OVER) позволяют выполнять такие проверки непосредственно в БД одним запросом, что часто эффективнее, чем выгружать все данные и анализировать их в коде теста. Это мощный инструмент для тестирования бизнес-логики, связанной с порядком, временем и группировкой данных.