MySQL中如何编写SQL查询简化双向关系数据表?
你遇到的问题本质是要去重无序的员工配对(即(x,y)和(y,x)视为同一对,只保留其中一条)。我来给你两种实用的MySQL解决方案,适配不同的需求:
方法1:统一整理为字典序有序配对
这种方法会把所有配对统一调整为emp字典序小于emp_dst的形式,确保每对只出现一次,逻辑简单且高效:
SELECT DISTINCT LEAST(emp, emp_dst) AS emp, GREATEST(emp, emp_dst) AS emp_dst FROM tableA;
效果说明:
- 对于
(a,b)和(b,a),会统一输出a | b - 对于
(c,d)和(d,c),会统一输出c | d - 单向配对(比如
b→c、d→b)会原样保留(因为没有反向配对,LEAST/GREATEST不会改变顺序)
方法2:保留原表中首次出现的配对
如果你希望严格保留原表中先出现的配对(比如原表先出现a→b,就保留它而排除后出现的b→a),可以用NOT EXISTS子句结合自增ID判断实现,结果和你给出的table B完全一致:
SELECT t1.emp, t1.emp_dst FROM tableA t1 WHERE NOT EXISTS ( SELECT 1 FROM tableA t2 -- 匹配反向配对 WHERE t2.emp = t1.emp_dst AND t2.emp_dst = t1.emp -- 确保反向配对的出现时间更早(用自增id判断顺序) AND t2.id < t1.id ) ORDER BY t1.id;
效果说明:
- 原表中
id=1的a→b先出现,id=4的b→a会被排除 - 原表中
id=2的a→d先出现,id=6的d→a会被排除 - 单向配对(
b→c、d→b、d→c)因为没有反向配对,会全部保留
为什么你的UNION尝试没生效?
UNION本身只会合并并去重完全相同的行,但(a,b)和(b,a)属于不同的行,UNION不会把它们视为重复项,所以单独用UNION无法解决这种无序配对的去重问题,必须结合逻辑判断来识别反向配对。
内容的提问来源于stack exchange,提问作者jhoss
相关产品推荐
相关产品推荐

