SQL中如何筛选姓名配对表的不重复名称对?
无序不重复姓名配对的SQL实现
原尝试语句的问题
当前写的查询存在两类硬伤:
- 语法不合法:SQL的
DISTINCT是作用于整行查询结果的全局修饰符,不支持在同一个SELECT列表里对多列分别单独标注DISTINCT。 - 逻辑不匹配:仅按
name1分组的规则,完全没有覆盖“两姓名交换顺序视为同一配对”的去重要求,根本识别不出(Harrison Ford, Mullah Omar)和(Mullah Omar, Harrison Ford)这类双向存储的重复配对。
实现核心逻辑
要去掉重复的无序配对,本质是把原本带存储顺序的二元组,转换成固定排列规则的结构:
强制让字符串字典序更靠前的姓名排在第一列,更靠后的排在第二列。这样不管原表中两个姓名的存储顺序怎么颠倒,转换后同一组配对的行结构会完全一致,后续通过分组就能正常完成去重。
可落地的查询写法
全方言兼容版本
通过CASE判断固定姓名顺序,对同配对的count值按业务规则聚合:
SELECT CASE WHEN name1 < name2 THEN name1 ELSE name2 END AS name_a, CASE WHEN name1 < name2 THEN name2 ELSE name1 END AS name_b, MAX(count) AS pair_count FROM f GROUP BY name_a, name_b;
注:count字段的聚合方式可按需调整,如果需要累加双向的统计值,把
MAX(count)替换成SUM(count)即可。
简化版(支持标量函数的数据库适用)
如果所用数据库支持LEAST()(取两个值中的较小值)、GREATEST()(取两个值中的较大值)函数,可将CASE逻辑简化为:
SELECT LEAST(name1, name2) AS name_a, GREATEST(name1, name2) AS name_b, MAX(count) AS pair_count FROM f GROUP BY name_a, name_b;
对应样例的输出结果
基于给出的表f数据,运行查询后会得到3组无重复的无序配对:
name_a name_b pair_count Harrison Ford Michael Caine 6 Harrison Ford Mullah Omar 3 Michael Caine Mullah Omar 2
刚好将原表中6行双向存储的重复配对,压缩为3组唯一的配对关系。
内容的提问来源于stack exchange,提问作者ERJAN
相关产品推荐
相关产品推荐

