Удаление одинаковых строк в PostgreSQL | OTUS

Удаление одинаковых строк в PostgreSQL

Если получилось, что в таблице отсутствует первичный ключ (primary key), скорее всего, среди записей есть дубликаты. Речь идёт о дублирующихся строках или случаях, когда дублируется одна либо более колонок. Посмотрим на таблицу с информацией о покупателях, где вторая по счёту строка полностью задублирована:

postgre_01_1-20219-e7203b.png

Чтобы удалить все дубликаты, нам подойдёт следующий запрос:

DELETE FROM customers WHERE ctid NOT IN
(SELECT max(ctid) FROM customers GROUP BY customers.*);

По умолчанию, уникальное для каждой записи поле ctid скрыто, однако оно существует в каждой таблице.

Тут следует заметить, что запрос довольно требователен к ресурсам, что следует учитывать при его использовании на рабочем проекте — просто будьте аккуратны.

В следующей ситуации повторяются значения полей.

postgre_02_1-20219-ee73a1.png

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

DELETE FROM customers WHERE ctid NOT IN
(SELECT max(ctid) FROM customers GROUP BY customer_id);

Если же информация важна, сначала давайте найдём записи с дубликатами:

SELECT * FROM customers WHERE ctid NOT IN
(SELECT max(ctid) FROM customers GROUP BY customer_id);

postgre_03_1-20219-c4c0dc.png

До удаления такой записи мы можем перенести её во временную таблицу либо заменить значение customer_id на другое.

Как бы там ни было, общая форма запроса на удаление вышеописанных записей будет выглядеть так:

DELETE FROM table_name WHERE ctid NOT IN (SELECT max(ctid) FROM table_name GROUP BY column1, [column 2,] );

Возможно, вам также будут интересны следующие статьи: — «Работа с конфигурацией в PostgreSQL»; — «Безопасное изменение типа поля в PostgreSQL»; — «Полезные команды в PostgreSQL»; — «Поиск «потерянных» значений в PostgreSQL».

По материалам «15 Advanced PostgreSQL Commands with Examples» и «10 Most Useful PostgreSQL Commands with Examples».

Не пропустите новые полезные статьи!

Спасибо за подписку!

Мы отправили вам письмо для подтверждения вашего email.
С уважением, OTUS!

Автор
1 комментарий
1

Запрос на 1.5 ляма строк подвис на пару дней. create table back_up."LOG_distinct" as with newtable as ( select row_number() OVER (PARTITION BY num_id) number_row, * from back_up."LOG" ) select * from newtable where number_row = 1 этот запрос создаст бекапную таблицу без дубликатов Далее из первой таблицы можно удалить все , и вставить из бекапной Экономия времени получилась существенной

Для комментирования необходимо авторизоваться
Популярное
Сегодня тут пусто