SQL: последний заказ пользователя из Москвы и процент скидки

Пример для PostgreSQL.

Короткий ответ

Что ответить на собеседовании

Пример для PostgreSQL. Справочник называем users, его ключ — usersid, как в условии. price — цена до скидки, discount — денежная сумма скидки; NULL в скидке считаем отсутствием скидки. Идентификаторы уникальны, время заказа заполнено. Город нормализован к значению Москва.

Подробный разбор

Ответ с пояснениями

Условие

У тебя есть таблица orders с заказами order_id, created_dt, user_id, price, discount
Также есть справочник по пользователям users_id, reg_date, city
Для каждого пользователя из москвы нужно вывести последний заказ и процент примененной скидки

Решение

Пример для PostgreSQL. Справочник называем users, его ключ — users_id, как в условии. price — цена до скидки, discount — денежная сумма скидки; NULL в скидке считаем отсутствием скидки. Идентификаторы уникальны, время заказа заполнено. Город нормализован к значению Москва.

«Последний» означает заказ за всю доступную историю: временной фильтр не задан. При одинаковом времени выбираем больший order_id как детерминированное правило разрешения совпадений.

WITH ranked AS (
    SELECT o.*,
           ROW_NUMBER() OVER (
               PARTITION BY user_id
               ORDER BY created_dt DESC NULLS LAST,
                        order_id DESC
           ) AS rn
    FROM orders AS o
)
SELECT u.users_id,
       r.order_id,
       r.created_dt,
       100.0 * COALESCE(r.discount, 0)
           / NULLIF(r.price, 0) AS discount_pct
FROM users AS u
LEFT JOIN ranked AS r
       ON r.user_id = u.users_id AND r.rn = 1
WHERE u.city = 'Москва'
ORDER BY u.users_id;

Пользователи без заказов сохраняются: поля заказа и процент будут NULL. При нулевой цене процент также неопределён. Условие rn = 1 находится в ON, чтобы не потерять строки без заказа.

Если discount уже задан процентом от 0 до 100, берут само значение, а не делят на цену. Если нужен последний заказ внутри периода [начало, конец), фильтр дат добавляют в CTE до нумерации. Оконные функции PostgreSQL

Практика в реальном времени

Подготовьтесь к следующему собеседованию

Interview Boost учитывает вакансию, резюме и технологии и помогает сформулировать ответ прямо во время интервью.

Начать подготовку