Найдите дубликаты в нескольких полях электронной почты - PullRequest
0 голосов
/ 07 августа 2020

У меня странное требование. Мне нужно найти повторяющиеся записи контактов в моей базе данных (должно быть просто). Моя проблема в том, что я должен сопоставить по имени, фамилии и ЛЮБОМУ из полей электронных писем, совпадающих между собой.

Exemple:
FirstName    | LastName    | Email           | WorkEmail            | AnotherEmail
John           Smith          jh@jh.com         test@test.com          yougettheIdea.com
John           Smith          test@test.com                              
John           Smith          imAdifferent.jh.com

Мне нужно Определить в этом примере, что Джон Смит в строках 1 и 2 является дублированной записью, а в строке 3 - нет. По сути, мне нужно запросить FirstName, соответствующее FirstName, LastName, соответствующее LastName, и любое из полей электронной почты, соответствующее любому из полей ... Возможно ли это вообще?

Я получил это для сопоставления по имени и фамилии , но электронных писем для меня слишком много:

SELECT * FROM
      (SELECT "FirstName","LastName","Email",","WorkEmail","AnotherEmail", count(*)
      OVER
        (PARTITION BY
          "FirstName",
          "LastName"
        ) AS count
      FROM Contact) tableWithCount
      WHERE tableWithCount.count > 1 ORDER BY count DESC;

Ответы [ 2 ]

0 голосов
/ 07 августа 2020

Я бы построил массив столбцов электронной почты, а затем проверял бы наличие дубликатов, используя оператор @> в обоих направлениях.

select *
from contact c1
where exists (select * 
              from contact c2
              where (c1.first_name, c1.last_name) = (c2.first_name, c2.last_name)
                and (    
                    array_remove(array[c1.email, c1.work_email, c1.another_email],null) @> array_remove(array[c2.email, c2.work_email, c2.another_email], null)
                 or array_remove(array[c1.email, c1.work_email, c1.another_email],null) <@ array_remove(array[c2.email, c2.work_email, c2.another_email], null) 
                )
                and c1.ctid <> c2.ctid
              );

Выражение c1.ctid <> c2.ctid используется, чтобы избежать сравнения строки с собой. Если в вашей таблице есть первичный или уникальный ключ, используйте вместо него этот столбец.

Онлайн-пример

0 голосов
/ 07 августа 2020

Я бы использовал здесь exists logi c, сравнивая каждый столбец электронной почты с каждым другим столбцом. Следующий запрос определяет все записи, которые не имеют повторяющуюся запись.

SELECT *
FROM Contact c1
WHERE NOT EXISTS (SELECT 1 FROM Contact c2
                  WHERE c2.LastName = c1.LastName AND c2.FirstName = c1.FirstName AND
                        c2.id <> c1.id AND  -- assuming there is a PK column id
                        (c2.Email = c1.Email OR c2.WorkEmail = c1.Email OR
                         c2.AnotherEmail = c1.Email
                         OR
                         c2.Email = c1.WorkEmail OR c2.WorkEmail = c1.WorkEmail OR
                         c2.AnotherEmail = c1.WorkEmail
                         OR
                         c2.Email = c1.AnotherEmail OR c2.WorkEmail = c1.AnotherEmail OR
                         c2.AnotherEmail = c1.AnotherEmail));

Если вместо этого вы хотите найти все повторяющиеся записи, измените NOT EXISTS на EXISTS.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...