Пример для PostgreSQL. Справочник называем users, его ключ — usersid, как в условии. price — цена до скидки, discount — денежная сумма скидки; NULL в скидке считаем отсутствием скидки. Идентификаторы уникальны, время заказа заполнено. Город нормализован к значению Москва.
SQL: последний заказ пользователя из Москвы и процент скидки
Пример для PostgreSQL.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
У тебя есть таблица 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