2017-09-05 525 views
1

我的客户表:SQL查询来查找重复行并返回两者的ID

id | name | email 
-------------------------- 
1 | Rob | [email protected] 
2 | Jim | [email protected] 
3 | Dave | [email protected] 
4 | Fred | [email protected] 
5 | Ben | [email protected] 
6 | Tom | [email protected] 

我试图写重复的电子邮件地址,但返回的所有行的SQL查询...我'd像查询结果返回原始ID 重复的ID。 (原来的ID是重复的电子邮件中第一次出现。)

期望的结果:

original_id | duplicate_id | email 
------------------------------------------- 
      1 |   2 | [email protected] 
      3 |   5 | [email protected] 
      3 |   6 | [email protected] 

我的研究,到目前为止已表示它可能涉及某种自我的加入,但我卡上实际执行。谁能帮忙?

+0

如果想要什么就有什么的电子邮件存储数(大于2)倍?它应该如何显示在“duplicate_id”列中? –

+0

这是一个实际问题还是一些随机测试用例? – Amit

回答

1
select 
    orig.original_id, 
    t.id as duplicate_id, 
    orig.email 
from t 
    inner join (select min(id) as original_id, email 
       from t 
       group by email 
       having count(*)>1) orig on orig.email = t.email 
having t.id!=orig.original_id 

子查询,我们可以找到所有的IDS与重复的电子邮件。

然后,我们通过电子邮件和每一个使用最少的ID作为原始

UPDATE加入子查询:http://rextester.com/BLIHK20984克隆@Tim Biegeleisen的回答

+0

有时,请求的查询并不总是最好的答案。 –

+0

由于测试用例的原因,我一般同意并且+1您的答案。我甚至分叉你的测试我的) – StanislavL

3

我们可以处理这个使用加入,但我实际上可能去生成ID的对应重复一个CSV列表中的选项:

SELECT 
    email, 
    GROUP_CONCAT(id ORDER BY id) AS duplicate_ids 
FROM yourTable 
GROUP BY email 
HAVING COUNT(*) > 1 

从功能上来讲,这给你你想要的信息相同你的问题,但在我看来,这是一个非常简化的形式。因为我们在连接时订购了id值,所以原始id将始终首先出现在CSV列表的左侧。另外,如果您有很多副本,您的请求输出可能变得冗长而难以阅读。

输出:

enter image description here

演示在这里:

Rextester

+0

不完全是问题要求。它将连续的重复组合在一起。如果例如重复项需要删除,它将无法工作。 – StanislavL

+0

@StanislavL在哪里看到删除重复的要求? –

+0

要求是有3行不是2,并有原始的ID(我猜第一个) – StanislavL