SQL Server 2008 дедупликация - PullRequest
       9

SQL Server 2008 дедупликация

1 голос
/ 17 декабря 2010

Короче говоря, я взял на себя проект, и таблица в базе данных серьезно нуждается в дедупликации. Таблица выглядит так:

supply_req_id | int      | [primary key]
supply_req_dt | datetime | 
request_id    | int      | [foreign key]
supply_id     | int      | [foreign key]
is_disabled   | bit      |

Дублирование существует с записями, имеющими одинаковые request_id и supply_id. Я хотел бы найти лучший способ для устранения этой таблицы.

[EDIT]
@Kirk_Broadhurst, спасибо за вопрос. Поскольку на supply_req_id нигде нет ссылок, я бы сказал, что сначала сохраните, удалите все последующие вхождения.

Счастливых праздников

Ответы [ 3 ]

3 голосов
/ 17 декабря 2010

Это создает ранг для каждой строки в группе (supply_req_dt, request_id), начиная с 1 = наименьший supply_req_id. Любой обман имеет значение> 1

;WITH cDupes AS
(
    SELECT
     supply_req_id,
     ROW_NUMBER() OVER (PARTITION BY supply_req_dt, request_id ORDER BY supply_req_id) AS RowNum
    FROM
     MyTable
)
DELETE
   cDupes
WHERE
   RowNum > 1

Затем добавьте уникальное ограничение или INDEX

CREATE UNIQUE INDEX IXU_NoDupes ON MyTable (supply_req_dt, request_id)
2 голосов
/ 17 декабря 2010

Вам необходимо уточнить ваше правило для определения того, какую запись вести в случае «совпадения» - самой последней, самой ранней, той, которая имеет is_disabled true или false?

Onceвы определили это правило, а все остальное довольно просто:

  1. выберите записи, которые вы хотите сохранить - distinct records
  2. присоединятся к исходной таблице, чтобы получитьидентификаторы для этих записей.
  3. удаляйте все, что не входит в объединенный набор данных.

Итак, допустим, вы хотите сохранить самые последние записи любой «дублированной» пары.Ваш запрос будет выглядеть следующим образом:

DELETE FROM [table] WHERE supply_req_id NOT IN
(SELECT supply_req_id from [table] t 
INNER JOIN
    (SELECT MAX(supply_req_dt) dt, request_id, supply_id 
    FROM [table] 
    GROUP BY request_id, supply_id) d
ON t.supply_req_dt = d.dt
AND t.request_id = d.request_id 
AND t.supply_id = d.supply_id)

Выгода в том, что если supply_req_dt также дублируется, то вы сохраните оба дубликата.Чтобы исправить это, нужно сделать еще один group by и выбрать верхний id

select MAX(supply_req_id), supply_req_dt, request_id, supply_id 
group by supply_req_dt, request_id, supply_id 

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

2 голосов
/ 17 декабря 2010

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

Как удалить повторяющиеся строки из таблицы в SQL Server http://support.microsoft.com/kb/139444

...