Как фильтровать только актуальные данные в SQL запросе?
Ответ от нейросети
sobes.tech AI
Что хотят услышать интервьюеры:
Нужно уметь отделять «текущую» запись от истории изменений. Обычно для этого используют признак актуальности, дату окончания действия или оконные функции. Важно показать, что фильтрация зависит от модели хранения данных, а не от одного универсального SQL-приёма.
Определение:
Актуальные данные — это записи, которые считаются действующими на момент запроса. Чаще всего это означает, что запись имеет признак is_current = 1, либо у неё нет даты завершения (end_date IS NULL), либо она имеет самый свежий updated_at/версию среди дублей.
Способ фильтрации выбирают в зависимости от схемы:
- если есть флаг актуальности — фильтруют по нему;
- если есть период действия — проверяют текущую дату в диапазоне;
- если есть история версий — выбирают последнюю запись по ключу объекта;
- если нужна одна запись на сущность — используют
ROW_NUMBER()илиMAX()в подзапросе.
Пример использования:
-- Вариант 1: есть флаг актуальности
SELECT *
FROM customers
WHERE is_current = 1;
-- Вариант 2: есть период действия
SELECT *
FROM prices
WHERE CURRENT_DATE BETWEEN valid_from AND COALESCE(valid_to, CURRENT_DATE);
-- Вариант 3: нужно выбрать последнюю версию по клиенту
WITH ranked AS (
SELECT
c.*,
ROW_NUMBER() OVER (
PARTITION BY customer_id
ORDER BY updated_at DESC
) AS rn
FROM customer_history c
)
SELECT *
FROM ranked
WHERE rn = 1;
Пояснение кода:
В первом запросе выбираются только строки, помеченные как текущие через is_current = 1. Это самый простой и быстрый вариант, если флаг поддерживается корректно.
Во втором запросе актуальность определяется временем действия записи. CURRENT_DATE BETWEEN valid_from AND COALESCE(valid_to, CURRENT_DATE) оставляет только те строки, для которых текущая дата попадает в период действия. COALESCE помогает обработать открытый интервал, если дата окончания не заполнена.
В третьем запросе используется оконная функция ROW_NUMBER(). Она нумерует версии внутри каждого customer_id по убыванию updated_at, и rn = 1 оставляет только самую свежую запись.
Если кода нет, логика всё равно одна: сначала определить правило актуальности в модели данных, затем применить соответствующий фильтр.
Ключевые моменты:
- Способ фильтрации зависит от того, как в таблице хранится история.
- Самые частые варианты: флаг актуальности, период действия, последняя версия записи.
- Для выбора одной строки на сущность удобно использовать
ROW_NUMBER() OVER (PARTITION BY ...). - При фильтрации по датам важно учитывать границы интервала и
NULLв поле окончания. - Для больших таблиц лучше, чтобы поля фильтрации были индексированы.
- Если данные поступают из DWH/ELT-процессов, актуальность часто определяется витриной, а не исходной таблицей.