использование разбиения по выражению в операторе удаления postgresql - PullRequest
0 голосов
/ 22 сентября 2019

Я пытаюсь отладить приведенный ниже код.Я получаю сообщение об ошибке ERROR: синтаксическая ошибка в или около "(".

Моя цель удалить дубликаты записей в таблице

 delete FROM (SELECT *,
                         ROW_NUMBER() OVER (partition BY snapshot,col1,col2,col3,col4,col5) AS rnum
                 FROM table where snapshot='2019-08-31')  as t
          WHERE t.rnum > 1;

Ответы [ 2 ]

0 голосов
/ 22 сентября 2019

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

delete from t
    where snapshot = '2019-08-31' and
          id > (select min(id)
                from t t2
                where t2.snapshot = t.snapshot and
                      t2.col1 = t.col1 and
                      t2.col2 = t.col2 and
                      t2.col3 = t.col3 and
                      t2.col4 = t.col4 and
                      t2.col5 = t.col5
               );

Примечание. При этом также предполагается, что столбцы не NULL.Вы можете заменить = на is not distinct from, если возможно NULL s.

Если у вас много дубликатов и нет столбца идентификаторов, вам может быть проще удалить и повторно вставить данные:

create table temp_snapshot as
    select distinct on (col1, col2, col3, col4, col5) t.*
    from t
    where snapshot = '2019-08-31'
    order by col1, col2, col3, col4, col5;

delete from t
    where col1, col2, col3, col4, col5;

insert into t
    select *
    from temp_snapshot;

Если ваша таблица разбита на snapshot (возможно, это очень хорошая идея), вы можете вместо этого удалить раздел и затем снова добавить данные. Этот процесс обычно быстрее, чем удаление записей.

0 голосов
/ 22 сентября 2019

попробуйте, как показано ниже

DELETE FROM table a
WHERE a.ctid <> (SELECT min(b.ctid)
                 FROM   table b
                 WHERE  a.snapshot = b.snapshot
                          and a.col1=b.col1 and a.col2=b.col2);
...