Попробуйте что-то вроде этого:
Таблица
create table test (
id serial,
data jsonb
);
Данные
insert into test (data) values
('{"name": "foo1", "last_updated": "2019-10-06T09:29:30.000Z"}'),
('{"name": "foo1", "last_updated": "2019-10-06T01:29:30.000Z"}'),
('{"name": "foo1", "last_updated": "2019-10-07T01:29:30.000Z"}'),
('{"name": "foo2", "last_updated": "2019-10-06T09:29:30.000Z"}'),
('{"name": "foo2", "last_updated": "2019-10-06T01:29:30.000Z"}'),
('{"name": "foo2", "last_updated": "2019-10-06T02:29:30.000Z"}');
Запрос
with latest as (
select data->>'name' as name, max(data->>'last_updated') as last_updated
from test
group by data->>'name'
)
delete from test t
where not exists (
select 1 from latest
where t.data->>'name' = name
and t.data->>'last_updated' = last_updated
);
select * from test;
Пример
https://dbfiddle.uk/?rdbms=postgres_10&fiddle=2415e6f2c9c7980e69d178a331120dcd
Возможно, вам придется проиндексировать свой столбец jsonb, например create index on test((data->>'name'));
; вы можете сделать это и для last_updated.
Я предполагаю, что у пользователя нет идентичного last_updated.
Если это предположение неверно, вы можете попробовать следующее:
with ranking as (
select
row_number() over (partition by data->>'name' order by data->>'last_updated' desc) as sr,
x.*
from test x
)
delete from test t
where not exists (
select 1 from ranking
where sr = 1
and id = t.id
);
В этом случае мы сначала даем серийный номер записям пользователей. Время latest_updated каждого пользователя получает sr 1.
Затем мы просим базу данных удалить все записи, которые не соответствуют идентификатору sr 1.
Пример: https://dbfiddle.uk/?rdbms=postgres_10&fiddle=dba1879a755ed0ec90580352f82554ee