Выберите n-ю самую последнюю строку из нескольких групп

Используя Oracle 12c, у меня есть таблица table1, подобная этой:

ID    DATA1    DATA2    LAST_UPDATE_TIMESTAMP
1       1        2            time_stamp1
2       1        2            time_stamp2
3       2        1            time_stamp3
4       2        2            time_stamp4
5       1        2            time_stamp5
6       1        1            time_stamp6
7       2        2            time_stamp7
8       1        1            time_stamp8
9       2        1            time_stamp9
10      1        2            time_stamp10

DATA1 AND DATA2 имеет только четыре возможные пары:

1,1 1,2 2,1 2,2

Как получить идентификаторы каждой пары, если они упорядочены по LAST_UPDATE_TIMESTAMP, которые являются n-ми последними записями?

Например, если LAST_UPDATE_TIMESTAMP уже упорядочено в порядке убывания, то для самой последней пары идентификаторы четырех пар будут 1,3,4,6. Для второго самого последнего это будет 2,7,8,9.


Решение

Спасибо @kordirko. Это SQL, который я использую

SELECT ID
FROM (
SELECT t.*,
       row_number() 
       over (partition by data1, data2 
             ORDER BY last_updated_timestamp DESC) as rn
       FROM table1 t
)
WHERE rn = n --n means the nth most recent, starts from 1

person Peike    schedule 06.07.2016    source источник


Ответы (2)


Пытаться:

SELECT ID, DATA1, DATA2, LAST_UPDATE_TIMESTAMP,
       rn -- this is a number of pair: 1-first most recent, 2-second most recent etc.
FROM (
   SELECT t.*,
          row_number() 
             over (partition by data1, data2 
                   ORDER BY last_updated_timestamp DESC) as Rn
)
WHERE rn <= 5 -- where 5 is a limit ==> you will get at most 5 most recent records for each pair
person krokodilko    schedule 06.07.2016
comment
Спасибо. Это именно то, что я хочу. - person Peike; 06.07.2016

Если вы хотите, чтобы возвращалась только одна строка, вы можете использовать предложение fetch first (технически называемое «предложением ограничения строк»). Например, чтобы получить пятую строку для (1, 1):

select t.*
from table1 t
where data1 = 1 and data2 = 1
order by last_update_timestamp desc
offset 4
fetch next 1 row only;

Обратите внимание, что offset в данном случае равно «4», а не «5», потому что четыре строки пропускаются, чтобы добраться до пятой строки. Для повышения производительности рекомендуется индекс (data1, data2, last_upate_timestamp).

person Gordon Linoff    schedule 06.07.2016
comment
Спасибо за ответ! Я думаю, что я хочу спросить, чтобы на самом деле получить n-е самое последнее из каждой пары. Вопрос обновлен. - person Peike; 06.07.2016