如何编写SQL查询比对两表差异并更新domain字段?
要处理domain的编码映射匹配,核心思路是先把table1的domain转换成和table2对应的标准值,再进行比对。下面分两种场景给出完善后的查询,同时提供两种实现映射的方式(适配不同规模的映射规则):
方案一:用CASE表达式(适合映射规则较少的情况)
如果你的domain映射不多,可以直接在SQL里用CASE语句定义转换规则:
场景1:找出真正存在差异的记录
SELECT t1.schema, t1.table, t1.domain FROM table1 t1 INNER JOIN table2 t2 ON t1.schema = t2.schema AND t1.table = t2.table -- 将table1的domain转换为table2对应的匹配值,再判断是否不相等 AND CASE t1.domain WHEN 'supply' THEN 'manufacture' -- 添加你的映射规则 -- 可继续添加更多WHEN子句,比如WHEN 'xxx' THEN 'yyy' ELSE t1.domain -- 无映射的domain用原值 END != t2.domain
这个查询会排除supply和manufacture这种映射匹配的记录,只返回真正domain不匹配的行(比如示例中的abc_t.sample)。
场景2:更新table2中真正有差异的domain
UPDATE table2 t2 SET domain = t1.domain FROM table1 t1 WHERE t1.schema = t2.schema AND t1.table = t2.table AND CASE t1.domain WHEN 'supply' THEN 'manufacture' ELSE t1.domain END != t2.domain
执行后,table2的abc_t.sample会被更新为sale,而cde_t.test因为映射匹配会保留原有的manufacture,和你期望的输出一致。
方案二:用映射表(适合映射规则较多或需要动态维护的情况)
如果映射规则很多,或者以后需要频繁修改,建议创建专门的映射表维护对应关系:
首先创建映射表(永久表或临时表均可):
CREATE TABLE domain_mapping ( source_domain VARCHAR(50) PRIMARY KEY, target_domain VARCHAR(50) NOT NULL ); -- 插入你的映射规则 INSERT INTO domain_mapping VALUES ('supply', 'manufacture'); -- 可继续插入更多映射,比如('xxx', 'yyy')
场景1:找出真正存在差异的记录
SELECT t1.schema, t1.table, t1.domain FROM table1 t1 INNER JOIN table2 t2 ON t1.schema = t2.schema AND t1.table = t2.table LEFT JOIN domain_mapping dm ON t1.domain = dm.source_domain -- 有映射就用target_domain,无映射用原domain,再和table2的domain比对 AND COALESCE(dm.target_domain, t1.domain) != t2.domain
场景2:更新table2中真正有差异的domain
UPDATE table2 t2 SET domain = t1.domain FROM table1 t1 LEFT JOIN domain_mapping dm ON t1.domain = dm.source_domain WHERE t1.schema = t2.schema AND t1.table = t2.table AND COALESCE(dm.target_domain, t1.domain) != t2.domain
这种方式的优势是后续修改映射规则只需更新domain_mapping表,无需改动业务SQL,扩展性更强。
内容的提问来源于stack exchange,提问作者Ram
相关产品推荐
相关产品推荐

