Создадим таблицу и заполним ее данными:
create table kk_client_rating(clientname varchar2(100), dt date, rating integer);
insert into kk_client_rating(clientname, dt, rating) values('Сыроедов', to_date('28.06.2012','dd.mm.yyyy'), 100);
insert into kk_client_rating(clientname, dt, rating) values('Сыроедов', to_date('29.06.2012','dd.mm.yyyy'), 90);
insert into kk_client_rating(clientname, dt, rating) values('Сыроедов', to_date('30.06.2012','dd.mm.yyyy'), 85);
insert into kk_client_rating(clientname, dt, rating) values('Сыроедов', to_date('30.06.2012','dd.mm.yyyy'), 100);
insert into kk_client_rating(clientname, dt, rating) values('Жирнов', to_date('25.06.2012','dd.mm.yyyy'), 100);
insert into kk_client_rating(clientname, dt, rating) values('Жирнов', to_date('27.06.2012','dd.mm.yyyy'), 85);
insert into kk_client_rating(clientname, dt, rating) values('Жирнов', to_date('28.06.2012','dd.mm.yyyy'), 85);
insert into kk_client_rating(clientname, dt, rating) values('Булочкин', to_date('25.06.2012','dd.mm.yyyy'), 85);
insert into kk_client_rating(clientname, dt, rating) values('Булочкин', to_date('29.06.2012','dd.mm.yyyy'), 80);
insert into kk_client_rating(clientname, dt, rating) values('Булочкин', to_date('29.06.2012','dd.mm.yyyy'), 85);
Напишем требуемый оператор с использованием max() keep(dense_rank):
delete from kk_client_rating
where (clientname, dt, rating) not in
(select clientname,
max(dt),
max(rating) keep(dense_rank last order by dt)
from kk_client_rating
group by clientname);
Проверим результат удаления:
select * from kk_client_rating;
Напишем другой вариант через rowid и row_number():
delete from kk_client_rating
where rowid not in (select rowid
from (select rowid,
row_number() over(partition by clientname order by dt desc, rating desc) rn
from kk_client_rating)
where rn = 1);
Проверим результат удаления:
select * from kk_client_rating;