поиск дубликатов кросс-полей в postgresql - PullRequest
1 голос
/ 06 августа 2020

У меня есть таблица контактов. Таблица содержит столбец mobile_phone, а также столбец home_phone. Я хочу получить все повторяющиеся контакты, где дубликат - это два контакта с общим номером телефона. Если mobile_phone контакта A совпадает с home_phone контакта B, это также дубликат. Вот пример трех контактов, которые должны совпадать.

contact_id|mobile_phone|home_phone|other columns such as email.......|...
-------------------------------------------------------------------------
111       |9748777777  |1112312312|..................................|...
112       |1112312312  |null      |..................................|...
113       |9748777777  |0001112222|..................................|...

Вот запрос, который находит дубликаты, но не по полям.

select mobile_phone from contacts group by mobile_phone HAVING count(*) > 1 order by mobile_phone

Ответы [ 2 ]

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

Чтобы найти все строки с (перекрестными столбцами) повторяющимися номерами телефонов:

SELECT *
FROM   contacts c
WHERE  EXISTS (
   SELECT FROM contacts x
   WHERE  x.mobile_phone IN (c.mobile_phone, c.home_phone)
       OR x.home_phone   IN (c.mobile_phone, c.home_phone)
   AND x.contact_id <> c.contact_id  -- except self
   );

Чтобы найти все повторяющиеся номера телефонов в двух столбцах:

SELECT DISTINCT phone
FROM  (
   SELECT mobile_phone AS phone
   FROM   contacts c
   WHERE  EXISTS (
      SELECT FROM mobile_phone x
      WHERE  c.mobile_phone IN (x.mobile_phone, x.home_phone)
      AND    c.contact_id <> x.contact_id  -- except self
      )
   UNION ALL
   SELECT home_phone
   FROM   contacts c
   WHERE  EXISTS (
      SELECT FROM mobile_phone x
      WHERE  c.home_phone = x.home_phone   -- cross-over covered by 1s SELECT
      AND    c.contact_id <> x.contact_id  -- except self
      )
   ) sub;

Повторение одного и того же номера в обоих столбцах строки не подходит. Я не думаю, что вы захотите включить их. (По-прежнему будет шум, который стоит запретить с помощью ограничения CHECK.)

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

Использовать оконные функции:

select c.*
from (select c.*, count(*) over (partition by mobile_phone) as cnt
      from contacts c
     ) c
where cnt > 1;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...