SQL: удалить почти повторяющиеся строки, которые отличаются не более чем на x секунд по метке времени, и сохранить самые старые - PullRequest
0 голосов
/ 28 июня 2018

У меня есть таблица с кучей строковых атрибутов и меткой времени. Первичный ключ состоит из 4 строковых атрибутов и метки времени. Строки создаются путем анализа сообщений журнала. К сожалению, одно событие создает несколько сообщений журнала с идентичным содержимым, кроме метки времени, которая отличается на несколько секунд. Так что теперь у меня есть много строк, которые идентичны по каждому атрибуту, но отметка времени и все отметки времени находятся в 15-секундном интервале. Я хочу удалить все «дубликаты» (здесь дубликаты, означающие, что все атрибуты равны, кроме метки времени и метки времени отличаются не более чем на 15 секунд), кроме строки с самой старой меткой времени.

Версия Postgres - 9,6.

Мне удалось написать запрос, показывающий мне все такие «повторяющиеся» пары, но я был в тупике, когда нашел решение удалить все, кроме самой старой строки. Я не смог адаптировать ни одно из решений для удаления дубликатов здесь, на stackoverflow. Вероятно, нужно что-то с group by и удалить * из блокировки, где нет (выберите min (timestamp) ...):

Запрос, показывающий «повторяющиеся» пары:

select * 
from interlock i1
inner join interlock i2
on
i1.A = i2.A and
i1.B = i2.B and
i1.C = i2.C and
i1.D = i2.D and
i1.E = i2.E and
i1.F = i2.F and
i1.G = i2.G and
i1.H = i2.H and
i1.I = i2.I and
i1.J = i2.J and
i1.K = i2.K and
i1.timestamp <> i2.timestamp and
abs(extract(epoch from i1.timestamp) - extract(epoch from i2.timestamp)) < 15;

Ответы [ 2 ]

0 голосов
/ 29 июня 2018

Вот что я в итоге использовал:

delete from interlock i1
where exists
(select 1 from interlock i2 
where i2.room = i1.room
and i2.interlock_device = i1.interlock_device
and i2.interlock_name = i1.interlock_name
and i2.title = i1.title
and i2.information = i1.information
and i2.explanation = i1.explanation
and i2.interlock_id = i1.interlock_id
and i2.error_id = i1.error_id
and i2.severity = i1.severity
and i2.acknowledged = i1.acknowledged
and i2.target = i1.target
and i2.timestamp < i1.timestamp
and i2.timestamp + interval '15 second' > i1.timestamp);
0 голосов
/ 28 июня 2018

Вы можете использовать delete:

delete from interlock i
    from interlock i2
    where i2.a = i.a and . . .
          i2.timestamp > i.timestamp and
          i2.timestamp < i.timestamp + interval '15 second';
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...