У меня есть такая таблица в моей базе данных Oracle. (версия 21С)
UserId Date Objective Value
------------------------------------------------
1 2022-05-19 14:56:41 Test y 22
2 2022-02-19 14:56:41 Test y 44
1 2022-06-19 14:56:41 Test y 58
5 2022-07-19 14:56:41 Test y 98
4 2022-08-19 14:56:41 Test y 25
3 2022-09-19 14:56:41 Test y 54
1 2022-10-19 14:56:41 Test y 41
2 2022-06-09 14:56:41 Test y 52
2 2022-05-05 14:56:41 Test y 44
1 2022-04-22 14:56:41 Test y 48
2 2022-07-19 14:56:41 Test y 88
1 2022-01-10 14:56:41 Test y 4
2 2022-03-19 14:56:41 Test y 2
3 2022-02-19 14:56:41 Test y 44
Я хотел бы вернуть строки, но максимум 3 строки с одним и тем же идентификатором пользователя. Если UserId присутствует в таблице более 3 раз, мне нужно вернуть 3 последние строки (упорядочение по дате).
Например, с данными, которые я дал, я должен вернуть в общей сложности 10 строк (3 строки для UserId 1 (3 более поздних), 3 строки для UserId 2 (3 более поздних), 2 строки для UserId 3 (потому что только 2 записей) , 1 строка для UserId 4 (потому что только 1 запись) и 1 строка для UserId 5 (потому что только 1 запись)).
Я не знаю, как это сделать в одном запросе, если это возможно.
Заранее спасибо !
Для этого лучше всего подойдет функция ROW_NUMBER()
. Он похож на RANK/DENSE_RANK
, за исключением того, что он всегда (произвольно) присваивает разное значение каждой строке, даже в случае коллизий (одно и то же значение в столбце(ах) ORDER BY
), поэтому вы можете легко применить правило «дайте мне не более 3 правило строк:
SELECT *
FROM (SELECT x.*,
ROW_NUMBER() OVER (PARTITION BY userid ORDER BY datecol DESC) seq
FROM tablename x)
WHERE seq <= 3
Предложение PARTITION BY
определяет сегменты, в которых выполняется подсчет. Для каждого отдельного значения столбца(ов), указанного в PARTITION BY
, выполняется отдельный подсчет (и упорядочивание, если указано). Именно так вы достигаете эффекта «X строк на каждый идентификатор пользователя».
Взгляните на функцию ROW_NUMBER() :) docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/…