如何创建具有重复联系人的新表

时间:2012-03-28 13:45:27

标签: sql oracle

我正在尝试创建需要在我的users表中查找重复用户的sql过程或函数(如果用户有相同的电子邮件,则重复)。我想将用户保存在这样的新表中:

id | user_id | duplicate_users

duplicate_users将包含具有与user_id相同的电子邮件的用户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 个答案:

答案 0 :(得分:3)

“用户数组”是什么意思?你的意思是存储集合数据类型?一个CSV列表?术语“数组”并不真正适合Oracle领域。

此外,根据您所要求的性质,您希望密钥成为电子邮件,而不是其中一个ID,否则您将获得每个组合。

例如,用户a和b各自都有电子邮件“bob@inter.net”。您的查询将有

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

我认为你想要的是

bob@inter.net,(a,b)

现在,要将该字段设为您可以使用的CSV列表:

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

如果您想将ids存储在oracle集合中,我也可以引导您朝这个方向发展。

编辑:根据您的评论。

好的,如果你想要完整的结果,那么请修改

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

我建议使用Oracle 11.1或10的wm_concat()等效项,或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

答案 1 :(得分:0)

SELECT 
 email, 
 COUNT(email) AS occurrences
FROM 
 users
GROUP BY 
 email
HAVING ( COUNT(email) > 1 );

答案 2 :(得分:0)

也许是这样的:

;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

这将为您提供重复

答案 3 :(得分:0)

您可以使用以下查询 @vulkanino发布的内容供您参考,您可以将此查询用于以下答案 -

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

此查询应该为您提供包含电子邮件的ID列表,其中包含任何其他ID,也就是我对您的问题所理解的内容。

如果我对你的问题的理解是错误的,请纠正我。