SQL使用UNION DISTINCT时忽略指定字段去重且保留该字段排序如何实现
解决方案
核心思路是先合并两个库的全量数据后,按照指定的去重规则做优先级排序,仅保留每个重复数据中新库的记录。
支持窗口函数的数据库方案(MySQL 8.0+/PostgreSQL/SQL Server等通用)
SELECT username, name, lastname, DB FROM ( SELECT username, name, lastname, DB, -- 按三个去重字段分组,DB值越小优先级越高,新库记录会排在分组第一位 ROW_NUMBER() OVER (PARTITION BY username, name, lastname ORDER BY DB ASC) AS rn FROM ( SELECT username, name, lastname, 1 AS DB FROM new_DB.users UNION ALL SELECT username, name, lastname, 2 AS DB FROM old_DB.users ) AS all_users ) AS ranked_users WHERE rn = 1 ORDER BY DB, lastname, name ASC;
方案说明
- 内层用
UNION ALL合并全量数据,比UNION DISTINCT性能更优,不需要提前做无意义的预去重 - 窗口函数的分区规则完全匹配你要求的三个去重判定字段,排序规则保证新库记录优先级更高
- 外层过滤仅保留每个分组优先级最高的记录,自动实现重复数据优先保留新库的需求
- 最终排序和要求完全一致,保留DB字段、新库所有数据排在最前面
低版本数据库兼容方案(如MySQL 5.7及更早版本)
SELECT username, name, lastname, MIN(DB) AS DB FROM ( SELECT username, name, lastname, 1 AS DB FROM new_DB.users UNION ALL SELECT username, name, lastname, 2 AS DB FROM old_DB.users ) AS all_users GROUP BY username, name, lastname ORDER BY DB, lastname, name ASC;
方案说明
- 利用
MIN(DB)聚合直接取每个分组的最小DB值,重复数据自然优先取新库的1,仅旧库的2只会在新库没有对应记录时返回,逻辑更简洁。
内容的提问来源于stack exchange,提问作者KimRoos10
相关产品推荐
相关产品推荐

