SQL查询去重:如何移除反向重复距离记录并加载到单表?
处理双向路线重复记录的SQL方案
嘿,这个问题其实挺常见的——毕竟像Mumbai↔Pune这种双向路线本质上是同一个行程对吧?我来给你几个实用的SQL方案,不管是清理已有的重复数据,还是加载时直接避免重复,都能搞定。
方案一:清理已有重复数据(保留一条)
核心思路是把每条路线的起点和终点按固定顺序(比如字母顺序)统一,这样反向路线就会生成相同的标识,再基于这个标识去重。
第一步:查询去重后的结果
先确认去重效果,用LEAST()和GREATEST()函数(大多数主流SQL数据库都支持,比如MySQL、PostgreSQL)来统一起点和终点:
SELECT LEAST(source, destination) AS standardized_source, GREATEST(source, destination) AS standardized_destination, distance FROM your_table GROUP BY LEAST(source, destination), GREATEST(source, destination), distance;
如果是SQL Server这类没有LEAST()/GREATEST()的数据库,可以用CASE WHEN替代:
SELECT CASE WHEN source < destination THEN source ELSE destination END AS standardized_source, CASE WHEN source > destination THEN source ELSE destination END AS standardized_destination, distance FROM your_table GROUP BY CASE WHEN source < destination THEN source ELSE destination END, CASE WHEN source > destination THEN source ELSE destination END, distance;
第二步:将去重后的数据写回原表
如果确认结果没问题,就可以把数据更新到原表(注意:操作前一定要备份原数据!):
-- 1. 创建临时表存储去重后的数据 CREATE TEMP TABLE temp_unique_routes AS SELECT LEAST(source, destination) AS source, GREATEST(source, destination) AS destination, distance FROM your_table GROUP BY LEAST(source, destination), GREATEST(source, destination), distance; -- 2. 清空原表(谨慎操作!) TRUNCATE TABLE your_table; -- 3. 插入去重后的数据 INSERT INTO your_table (source, destination, distance) SELECT source, destination, distance FROM temp_unique_routes;
方案二:加载数据时直接避免重复
如果是要新加载数据,不想事后清理,可以提前给表加约束,自动拦截重复的双向路线:
1. 添加生成列和唯一约束(以MySQL为例)
先给表加一个自动计算的route_key,用来标识统一后的路线:
ALTER TABLE your_table ADD COLUMN route_key VARCHAR(200) AS (CONCAT(LEAST(source, destination), '-', GREATEST(source, destination))) STORED; -- 给route_key加唯一约束,确保相同路线只能存一条 ALTER TABLE your_table ADD UNIQUE KEY uk_route_key (route_key);
2. 插入数据时自动忽略/更新重复项
现在插入数据时,遇到反向路线就会触发唯一约束,你可以选择忽略重复,或者更新现有记录:
-- 忽略重复数据 INSERT IGNORE INTO your_table (source, destination, distance) VALUES ('Mumbai', 'Pune', 150), ('Pune', 'Mumbai', 150), ('Delhi', 'Agra', 2000); -- 或者更新现有记录的distance(如果需要同步最新距离) INSERT INTO your_table (source, destination, distance) VALUES ('Mumbai', 'Pune', 150), ('Pune', 'Mumbai', 150), ('Delhi', 'Agra', 2000) ON DUPLICATE KEY UPDATE distance = VALUES(distance);
注意事项
- 备份优先:不管用哪种方案,操作生产数据前一定要备份,避免误删重要信息。
- 数据库兼容性:不同SQL方言的函数语法可能有差异,比如PostgreSQL用
ON CONFLICT替代ON DUPLICATE KEY UPDATE,需要根据你用的数据库调整。
内容的提问来源于stack exchange,提问作者Yogi chavan
相关产品推荐
相关产品推荐

