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

SQL中非传统重复数据筛选:双向关联行的去重方案

处理双向关联重复数据的优雅去重方法

这确实是处理关联类数据时非常常见的场景——双向配对被存成两行,但我们只需要保留其中一组就行。我来分享几个实用且优雅的解决方案,适配大多数主流SQL方言:

方法一:利用比较运算符直接过滤(最简洁)

这是最直接高效的方式,核心思路是只保留id1小于id2的行(反过来选大于的也行,保持规则一致就好)。这样不管双向配对怎么存储,只会留下其中一行:

SELECT id1, id2
FROM your_table
WHERE id1 < id2;

原理说明

比如你的示例数据里,ABC < DEF条件成立,这行会被保留;而DEF < ABC不成立,就会被过滤掉。如果你的ID是数字类型,这个逻辑同样适用。要是担心有NULL值,可以额外加个AND id1 IS NOT NULL AND id2 IS NOT NULL避免异常。

方法二:窗口函数分组去重(更灵活)

如果你的需求不止是去重,还需要自定义保留哪一行(比如保留最早插入的、或某一列有特定值的行),窗口函数会是更好的选择。我们可以用LEAST()和GREATEST()(大部分数据库支持)把双向配对统一成唯一的分组键,再用ROW_NUMBER()标记每组内的行,最后只取第一行:

SELECT id1, id2
FROM (
    SELECT 
        id1, 
        id2,
        ROW_NUMBER() OVER (
            PARTITION BY LEAST(id1, id2), GREATEST(id1, id2)
            ORDER BY id1 -- 这里可以换成你需要的排序规则,比如创建时间 create_time
        ) AS row_num
    FROM your_table
) AS filtered
WHERE row_num = 1;

兼容小提示

如果你的数据库不支持LEAST()和GREATEST()(比如SQL Server),可以用CASE语句替代:

-- 替代LEAST(id1, id2)
CASE WHEN id1 < id2 THEN id1 ELSE id2 END
-- 替代GREATEST(id1, id2)
CASE WHEN id1 > id2 THEN id1 ELSE id2 END

总结

  • 如果你只需要简单去重,方法一是最优解,代码简洁且性能最好,不需要子查询或窗口函数;
  • 如果你需要控制保留哪一行,方法二的灵活性更高,能应对更复杂的业务规则。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 14:02:44