2014-08-15 1 views
0

У меня есть таблица с столбцом bit с именем IsRetry. Я хочу удалить все повторяющиеся адреса электронной почты, которые не установлены как IsRetry. Если есть дубликаты IsRetry, я тоже хочу их удалить. Я попробовал разметку на IsRetry, но я все еще получаю сообщения, которые установлены как IsRetry, а не. SQL ниже удаляет дубликаты, но он хранит одно из каждого письма. Смысл, один набор как IsRetry, а другой нет. Должен ли я запускать запрос для удаления исходных дубликатов, а затем удалить все дубликаты, которые не являются IsRetry, или я могу сделать это в одном запросе?Удаление дубликатов из таблицы, которые не заданы с определенным значением

CREATE TABLE Emails 
(
    [EmailAddress] varchar(50) 
    ,[Md5Hash] NVARCHAR(32) 
    ,[IsRetry] bit 
); 

insert into Emails (EmailAddress,Md5Hash,IsRetry) 
    VALUES('[email protected]', '4d35f7e71ffa6246b55f14da99e18ede', 1) 
insert into Emails (EmailAddress,Md5Hash,IsRetry) 
    VALUES('[email protected]', '4d35f7e71ffa6246b55f14da99e18ede', 0) 
insert into Emails (EmailAddress,Md5Hash,IsRetry) 
    VALUES('[email protected]', 'c8e5b73cbe5438c62e9ca001929cb05d', 1) 
insert into Emails (EmailAddress,Md5Hash,IsRetry) 
    VALUES('[email protected]', 'c8e5b73cbe5438c62e9ca001929cb05d', 0) 
insert into Emails (EmailAddress,Md5Hash,IsRetry) 
    VALUES('someemail[email protected]', 'c8e5b73cbe5438c62e9ca001929cb05d', 0) 
insert into Emails (EmailAddress,Md5Hash,IsRetry) 
    VALUES('[email protected]', 'ddcb2ab8af5ff8c8040defebf471d5df', 1) 
insert into Emails (EmailAddress,Md5Hash,IsRetry) 
    VALUES('[email protected]', 'ddcb2ab8af5ff8c8040defebf471d5df', 1) 
insert into Emails (EmailAddress,Md5Hash,IsRetry) 
    VALUES('[email protected]', 'ddcb2ab8af5ff8c8040defebf471d5df', 0) 
insert into Emails (EmailAddress,Md5Hash,IsRetry) 
    VALUES('[email protected]', 'ddcb2ab8af5ff8c8040defebf471d5df', 0) 

;WITH cte 
AS(
    SELECT ROW_NUMBER() OVER (PARTITION BY Md5Hash,IsRetry ORDER BY (SELECT 0)) RN 
      ,IsRetry 
      ,EmailAddress 
    FROM Emails 
) 
DELETE FROM cte 
WHERE RN > 1 

Select * from Emails 

Here is the fiddle for it

ответ

3

Это звучит, как вы хотите, чтобы оставить только одно сообщение. Если установлено IsRetry, вы хотите, чтобы это был один набор. Если это так, то вы не хотите раздел от IsRetry. Вы хотите, чтобы в в пункте order by:

with todelete as (
    select e.*, 
      row_number() over (partition by EmailAddress 
           order by IsRetry desc) as seqnum 
    from Emails 
    ) 
delete from todelete 
    where seqnum > 1; 

Я изменил разделение использовать email. Возможно иметь два разных письма с одним и тем же хэш-кодом MD5.

+0

Это замечательно! Просто любопытно, каковы шансы столкновения MD5 с хэшей электронной почтой? Я знаю, что это возможно, учитывая фиксированную длину MD5, но он никогда не думал о столкновении. Итак, спасибо за головы! – DDiVita

+0

@DDiVita. , , Ладно, это очень, очень маловероятно, когда-либо случится со случайными адресами электронной почты (http://stackoverflow.com/questions/8852668/what-is-the-clash-rate-for-md5), но по-прежнему мало причин для используйте хеш-код вместо самого адреса электронной почты. –

Смежные вопросы