如何用SQL对guests表中互为室友的重复行进行去重?
解决住宿名单重复室友组合的SQL查询方案
要处理guests表中姓名和室友互为对方的重复行,核心思路是将每个室友组合标准化(让姓名按固定顺序排列),再基于标准化后的组合去重,只保留任意一行。以下是两种通用的实现方式:
通用窗口函数写法(支持MySQL、PostgreSQL、SQL Server等)
这种写法适配绝大多数数据库,通过给每个标准化的室友组合编号,只保留每组的第一行:
SELECT name, roommate, eventid FROM ( SELECT name, roommate, eventid, ROW_NUMBER() OVER ( PARTITION BY eventid, LEAST(name, roommate), GREATEST(name, roommate) ORDER BY (SELECT NULL) -- 随机保留一行,无需特定排序 ) AS rn FROM guests -- 可选:仅处理指定活动,去掉则处理所有活动 WHERE eventid = 'trip12' ) t WHERE rn = 1;
代码说明
LEAST(name, roommate)和GREATEST(name, roommate):把姓名和室友按字典序排序,让(A,B)和(B,A)生成完全相同的标准化组合PARTITION BY:按活动ID和标准化组合分组,给每组内的行分配序号- 外层筛选
rn=1:每个组合只保留一行
PostgreSQL简洁写法
如果使用PostgreSQL,可利用DISTINCT ON特性简化代码:
SELECT DISTINCT ON (eventid, LEAST(name, roommate), GREATEST(name, roommate)) name, roommate, eventid FROM guests WHERE eventid = 'trip12' ORDER BY eventid, LEAST(name, roommate), GREATEST(name, roommate);
内容的提问来源于stack exchange,提问作者MrCycling
相关产品推荐
相关产品推荐

