Используйте ROW_NUMBER с PARTITION BY id и порядком raw_dt DESC, load_id DESC. Во внешнем запросе оставьте rn = 2: это предпоследняя запись, а не предпоследняя уникальная дата.
Как выбрать предпоследнюю запись загрузки по id абонента?
Используйте ROW_NUMBER с PARTITION BY id и порядком raw_dt DESC, load_id DESC. Во внешнем запросе оставьте rn = 2: это предпоследняя запись, а не предпоследняя уникальная дата.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
Таблица abnt(load_id PRIMARY KEY, id, tarif_plan_id, raw_dt) хранит загрузки абонентов. id — абонент, load_id — уникальная запись. raw_dt NOT NULL; при совпадении времени больший load_id считается более поздним. Найдите предпоследнюю запись каждого абонента, исключив абонентов с одной загрузкой.
Ответ
Используйте ROW_NUMBER с PARTITION BY id и порядком raw_dt DESC, load_id DESC. Во внешнем запросе оставьте rn = 2: это предпоследняя запись, а не предпоследняя уникальная дата.
WITH ranked AS (
SELECT abnt.*, ROW_NUMBER() OVER (
PARTITION BY id ORDER BY raw_dt DESC, load_id DESC
) AS rn FROM abnt
)
SELECT load_id, id, tarif_plan_id, raw_dt
FROM ranked WHERE rn = 2 ORDER BY id;
Например, из загрузок 10, 11, 12 одного абонента при возрастающих датах будет выбрана 11. Одинаковое время не делает выбор случайным благодаря load_id. Нельзя группировать только по id и брать MAX(raw_dt): это выбирает последнюю дату и не сохраняет согласованность остальных полей.