如何基于两列值获取唯一行?info表特定组合去重需求咨询
解决无序组合去重的SQL查询方案
嘿,这个需求我之前做项目时也碰到过——核心就是把userid和groupid的无序组合(比如(5,1)和(1,5))当成重复项,只保留其中一行。给你两种实用的解决思路,适配不同的数据库环境:
方法一:窗口函数法(推荐,适用于MySQL 8+、PostgreSQL、SQL Server等支持窗口函数的数据库)
通过LEAST()和GREATEST()把无序的两个值转换成固定顺序的组合键,再用ROW_NUMBER()给每组编号,只取第一行:
SELECT id, userid, groupid FROM ( SELECT id, userid, groupid, -- 按有序的组合分组,给每组行编号 ROW_NUMBER() OVER ( PARTITION BY LEAST(userid, groupid), GREATEST(userid, groupid) ORDER BY id ASC -- 这里控制保留哪一行:ASC留id最小的,DESC留id最大的 ) AS row_num FROM info ) ranked_info WHERE row_num = 1;
说明:
LEAST(userid, groupid)取两个值里的较小值,GREATEST()取较大值,这样任何无序组合都会变成统一的有序键;ORDER BY id ASC可以改成你需要的规则,比如按记录创建时间(如果有该字段)排序,自由决定保留哪一条重复记录。
方法二:分组关联法(适用于不支持窗口函数的老版本数据库)
先通过分组找到每个无序组合对应的目标记录ID,再关联原表取出完整数据:
SELECT i.id, i.userid, i.groupid FROM info i INNER JOIN ( SELECT LEAST(userid, groupid) AS min_val, GREATEST(userid, groupid) AS max_val, MIN(id) AS target_id -- 这里选要保留的记录ID,MIN留最小的,MAX留最大的 FROM info GROUP BY min_val, max_val ) grouped_info ON i.id = grouped_info.target_id;
说明:
- 子查询先按有序组合分组,锁定每个组合要保留的ID;
- 如果你想保留最新的记录,直接把
MIN(id)换成MAX(id)即可。
内容的提问来源于stack exchange,提问作者Shopno Hin
相关产品推荐
相关产品推荐

