Удалить частичные дубликаты из таблицы без уникального столбца - PullRequest
1 голос
/ 01 января 2012

Мне нужно очистить записи из таблицы, в которой нет первичного ключа или уникального ограничения.

Определение таблицы:

create table person(
    name text,
    staff_id integer,
    work_code text,
    location
);

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

Ответы [ 2 ]

4 голосов
/ 02 января 2012

Поскольку вы

не должны заботиться о других столбцах, кроме имени и staff_id

Это может быть ваша процедура для очистки таблицы:

1.) Создайте временную таблицу из уникальных строк:

CREATE TEMP TABLE p_tmp AS
SELECT DISTINCT ON (name, staff_id)
       name, staff_id, work_code, location
FROM   person
ORDER  BY name, staff_id, work_code, location;

Я произвольно выбираю "первую строку для (name, staff_id) - минимум work_code и соответствует location.

2.) Пустая таблица:

TRUNCATE person;

3.) Повторно ВСТАВЬТЕ уникальные кортежи:

INSERT INTO person SELECT * FROM p_tmp;

Убедитесь, что дупс не поползает обратноДобавьте суррогатный первичный ключ:

ALTER TABLE person ADD COLUMN person_id serial PRIMARY KEY;
ALTER TABLE person ADD UNIQUE (name, staff_id);

или просто добавьте первичный ключ из нескольких столбцов:

ALTER TABLE person ADD PRIMARY KEY (name, staff_id);

В конце временная таблица будет удалена.сеанса автоматически.

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

0 голосов
/ 01 января 2012

Может быть, это?

select t.name, t.staff_id, t.work_code, t.location
from (
    select name, staff_id, work_code, location, count(*) nr
    from person
    group by name, staff_id, work_code, location
) t
where t.nr > 1;
...