Как создать новую таблицу с дублированными контактами - PullRequest
1 голос
/ 28 марта 2012

Я пытаюсь создать процедуру или функцию sql, которые должны найти дублирующихся пользователей в моей таблице пользователей (дубликаты на случай, если у пользователей одинаковые электронные письма) Я хочу сохранить пользователей в новой таблице, например:

id | user_id | duplicate_users

duplicate_users будет содержать массив идентификаторов пользователей, которые имеют тот же адрес электронной почты, что и user_id Это мой основной запрос, но он очень плохой, потому что я получаю много результатов.

SELECT  a.id user_id,
        a.email,
        b.id,
        dup_user_id
FROM    users a, 
        users b
WHERE   a.email = b.email
  AND   a.id != b.id

Спасибо заранее.

Ответы [ 4 ]

3 голосов
/ 28 марта 2012

Что вы подразумеваете под «массивом пользователей»? Вы имеете в виду хранение типа данных коллекции? Список CSV? Термин «Массив» в действительности не вписывается в сферу Oracle.

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

Например, у пользователей a и b есть электронная почта "bob@inter.net". Ваш запрос будет иметь

а, bob@inter.net, б b, bob@inter.net, a

И я думаю, что вы хотите

bob@inter.net, (а, б)

Теперь, чтобы сделать поле списком идентификаторов CSV, вы можете использовать:

SELECT  email,         
        listagg(id,',') WITHIN GROUP (ORDER BY ID) as list_of_ids        
FROM    users
GROUP BY email

Если вы хотите сохранить идентификаторы в коллекции оракулов, я могу направить вас и в этом направлении.

РЕДАКТИРОВАТЬ: на основе вашего комментария.

ОК, если вы хотите получить полные результаты, измените значение на

SELECT  a.id as id
        a.email as email,         
        listagg(b.id,',') WITHIN GROUP (ORDER BY ID) as list_of_ids        
FROM    users a, users b
where   a.email = b.email
and     a.id != b.id
GROUP BY a.id, a.email

Так что, если все пользователи a, b и c поделятся электронной почтой bob@inter.net, вы получите:

a, bob@inter.net, "b, c"

b, bob@inter.net, "a, c"

c, bob@inter.net, "a, b"

Если вы хотите удалить электронное письмо из запроса, тогда:

SELECT  a.id as id
        listagg(b.id,',') WITHIN GROUP (ORDER BY ID) as list_of_ids        
FROM    users a, users b
where   a.email = b.email
and     a.id != b.id
GROUP BY a.id

Кстати, если вы используете более старую версию Oracle, которая не поддерживает функцию агрегирования строк listagg, то вы сможете найти альтернативное решение здесь: http://www.oracle -base.com / Articles / Misc /StringAggregationTechniques.php

Я бы предложил использовать эквивалент wm_concat () для Oracle 11.1 или 10 или один из других для Oracle 9.

Итак, для Oracle 11.1 или 10 используйте:

SELECT  a.id as id
        a.email as email,         
        wm_concat(b.id) as list_of_ids        
FROM    users a, users b
where   a.email = b.email
and     a.id != b.id
GROUP BY a.id, a.email
0 голосов
/ 28 марта 2012

Может быть, что-то вроде этого:

;WITH CTE
AS
(
    SELECT
        ROW_NUMBER() OVER(PARTITION BY users.email ORDER BY users.email) RowNbr,
        users.id,
        users.email
    FROM
        users
)
SELECT
    *
FROM
    CTE
WHERE
    CTE.RowNbr>1

Это даст вам дубликаты

0 голосов
/ 28 марта 2012

вы можете использовать следующий запрос, который @vulkanino опубликовал для вашей справки, и вы можете использовать этот запрос для своего ответа следующим образом -

select ID --* 
  from users
 where email in 
      (
         SELECT email
           FROM users
          GROUP BY email
         HAVING ( COUNT(email) > 1 )
      )

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

пожалуйста, поправьте меня, если мое понимание вашего вопроса неверно ..

0 голосов
/ 28 марта 2012
SELECT 
 email, 
 COUNT(email) AS occurrences
FROM 
 users
GROUP BY 
 email
HAVING ( COUNT(email) > 1 );
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...