我有一张顾客表:
id | name | email
--------------------------
1 | Rob | spam@email.com
2 | Jim | spam@email.com
3 | Dave | ham@email.com
4 | Fred | eggs@email.com
5 | Ben | ham@email.com
6 | Tom | ham@email.com
我尝试编写一个SQL查询,返回所有包含重复电子邮件地址的行,但是...我希望查询结果返回原始ID 和重复的ID。 (原始ID是重复电子邮件的第一次出现。)
期望的结果:
original_id | duplicate_id | email
-------------------------------------------
1 | 2 | spam@email.com
3 | 5 | ham@email.com
3 | 6 | ham@email.com
到目前为止,我的研究表明它可能涉及某种自我加入,但我仍然坚持实际的实施。有人可以帮忙吗?
答案 0 :(得分:3)
我们可以使用连接来处理这个问题,但实际上我可能会选择一个生成与重复项相对应的CSV列表的选项:
SELECT
email,
GROUP_CONCAT(id ORDER BY id) AS duplicate_ids
FROM yourTable
GROUP BY email
HAVING COUNT(*) > 1
从功能上讲,这会在您的问题中提供您想要的相同信息,但在我看来,这是一种非常简化的形式。由于我们在连接时订购id
值,因此原始id
将始终首先显示在CSV列表的左侧。此外,如果您有许多重复项,您的请求输出可能会变得冗长且难以阅读。
<强>输出:强>
在这里演示:
答案 1 :(得分: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
通过子查询,我们可以找到包含重复项的电子邮件的所有ID。
然后我们通过电子邮件加入子查询,并且每个子查询使用最小id作为原始
更新:http://rextester.com/BLIHK20984克隆@Tim Biegeleisen的回答