Стандарт — ROW_NUMBER() OVER (PARTITION BY ключ ORDER BY дата DESC) во CTE, затем WHERE rn = 1: останется одна (последняя) запись на ключ. Для полных дублей строк, где совпадают все колонки, достаточно SELECT DISTINCT или GROUP BY по всем полям.
DISTINCT и GROUP BY убирают полные дубли строк (совпадают все колонки). ROW_NUMBER нужен, когда дубли по ключу, но строки различаются и надо выбрать конкретную — последнюю по дате, с максимальной суммой. ROW_NUMBER самый гибкий.
ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY updated_at DESC) AS rn во CTE, затем WHERE rn = 1. Если при равных датах нужны все строки, а не одна — взять RANK вместо ROW_NUMBER.
DISTINCT ON (user_id) ... ORDER BY user_id, updated_at DESC — короткий способ взять по одной строке на ключ без оконных функций. Работает только в PostgreSQL; в других СУБД эквивалент — ROW_NUMBER.
Агрегации · JOIN-запросы · Оконные функции · CTE (Common Table Expressions) · Подзапросы · Работа с датами · Строковые функции · Условная логика
Открыть весь SQL-тренажёр (576 задач) →