Как я могу удалить дубликаты записей (это сложный случай, строки не являются уникальными, но их содержание) - PullRequest
0 голосов
/ 10 февраля 2019

Я пользователь Postgres.У меня есть таблица с такой структурой:

CREATE TABLE ParticleInteraction
(
particle1id smallint,
particle2id smallint,
timestep smallint,
distance real
)

Таблица содержит информацию о взаимодействии частиц.Частицы и их положения хранятся в другой таблице (здесь нас это не волнует).Я создал функцию SQL для вычисления расстояния между частицей и сохранения результата в таблице «ParticleInteraction».Пока все хорошо, расстояние вычисляется и результат сохраняется в таблице.Проблема в том, что результат в «ParticleInteraction» включает в себя все возможные случаи (которые делают дублирование): например, скажем, у нас есть только две частицы, частиц 7 и частиц 11, и у нас есть только одноразовый шаг.Таким образом, результат в таблице будет:

particle1id   particle1id   timestep   distance
7             11            1          0
11            7             1          0

Как видите, две записи представляют одну и ту же информацию, даже если они не уникальны.Нам нужна только одна из этих двух записей.Независимо от того, какая из двух записей будет удалена.

Как я могу удалить одну из них?

Ответы [ 2 ]

0 голосов
/ 10 февраля 2019

Если они всегда повторяются, просто сделайте следующее

 delete from ParticleInteraction 
 where particle1id  > particle2id

Однако я считаю, что было бы намного проще избежать хранения дубликатов (используя условие particle1id > particle2id).

0 голосов
/ 10 февраля 2019

Вот один из методов:

delete ParticleInteraction pi
    where pi.particle2id > pi.particle1id and
          exists (select 1
                  from ParticleInteraction pi2
                  where pi2.particle2id = pi1.particle1id and
                        pi2.particle1id = pi1.particle2id and
                        pi2.timestep = pi.timestep
                 );

Я не уверен, нужно ли вам также проверять расстояние или если вы просто хотите, чтобы по одной строке на пару на временной шаг.

ЕслиВы не хотите изменять таблицу и просто хотите запрос, который возвращает одну строку для каждой конкретной пары, вы можете использовать distinct on:

select distinct on (least(pi.particle2id, pi.particle1id), greatest(pi.particle2id, pi.particle1id), timestamp),
       pi.*
from ParticleInteraction pi
order by least(pi.particle2id, pi.particle1id),
         greatest(pi.particle2id, pi.particle1id),
         timestep;
...