Оконные функции на помощь (снова):
select customer_id, service_name, accessed_time
from (
select customer_id, service_name, accessed_time,
rank() over (partition by customer_id order by accessed_time desc) as rank
from access_log
) dt
where dt.rank <= 2
Предполагается, что «последние два» означают «два последних».Оконная функция row_number
может быть более подходящей в зависимости от того, как вы хотите обрабатывать дубликаты.
Учитывая данные, подобные этим (извините, сегодня вечером я не чувствую, что образно):
=> select * from access_log order by customer_id, accessed_time;
customer_id | service_name | accessed_time
-------------+--------------+---------------------
1 | one | 2011-01-01 00:00:00
1 | two | 2011-01-02 00:00:00
1 | three | 2011-01-03 00:00:00
2 | two | 2011-01-02 00:00:00
2 | one | 2011-04-01 00:00:00
2 | three | 2011-05-03 00:00:00
приведенный выше запрос дает:
customer_id | service_name | accessed_time
-------------+--------------+---------------------
1 | three | 2011-01-03 00:00:00
1 | two | 2011-01-02 00:00:00
2 | three | 2011-05-03 00:00:00
2 | one | 2011-04-01 00:00:00