You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在SQL中查询同表内name、email、number重复的所有行

嘿,这个需求我熟!想要找出name、email、number完全重复的所有行(包括每一条重复记录),用GROUP BY确实搞不定,自连接又太麻烦,给你两个简洁好用的方案,尤其是第一个用窗口函数的方法,超省心!

原始数据表

name email number type
1 abc@example.com 10 A
1 abc@example.com 10 B
2 def@def.com 20 B
3 ggg@ggg.com 30 B
1 abc@example.com 10 A
4 hhh@hhh.com 60 A

期望结果

name email number type
1 abc@example.com 10 A
1 abc@example.com 10 B
1 abc@example.com 10 A

解决方案1:使用窗口函数(推荐)

这是最简洁高效的方法,不需要分组或者复杂的自连接,用COUNT() OVER(PARTITION BY ...)统计每个组合的出现次数,再筛选出次数大于1的所有行:

SELECT name, email, number, type
FROM (
    SELECT 
        name, email, number, type,
        -- 按name、email、number分组,统计每组的总行数
        COUNT(*) OVER (PARTITION BY name, email, number) AS duplicate_count
    FROM your_table_name -- 替换成你的实际表名
) AS temp
WHERE duplicate_count > 1;

原理说明:

  • PARTITION BY name, email, number会把数据按这三个字段的组合分成不同的组
  • COUNT(*) OVER()会计算每个组里的总行数,赋值给duplicate_count
  • 最后筛选出duplicate_count > 1的行,也就是所有属于重复组合的记录,自然保留了每行的type字段

解决方案2:使用EXISTS子查询

如果你的数据库不支持窗口函数(比如一些老版本的数据库),可以用这个方法,通过检查是否存在其他相同组合的行来筛选:

SELECT t1.name, t1.email, t1.number, t1.type
FROM your_table_name t1
WHERE EXISTS (
    SELECT 1
    FROM your_table_name t2
    WHERE t2.name = t1.name
      AND t2.email = t1.email
      AND t2.number = t1.number
      -- 排除当前行本身,这里用主键或数据库自带的行标识
      -- MySQL用t2.id != t1.id(若有主键id),Oracle用t2.ROWID != t1.ROWID,PostgreSQL用t2.ctid != t1.ctid
      AND t2.id != t1.id
);

这个方法的逻辑是:对于每一行t1,只要存在另一行t2和它的name、email、number完全相同,就保留t1。需要注意的是,你得有一个唯一标识每行的字段(比如主键),如果没有的话,窗口函数的方法会更靠谱。

测试一下这两个方法,用你给的原始数据,都会得到你想要的结果哦!

内容的提问来源于stack exchange,提问作者OldMcDonald

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 06:08:59