DB2/SQL Server两表行差异查询及重复行排查求助
嘿,我来帮你梳理下这两个问题的解决方案,都是日常做数据排查常用的思路:
一、关联查询没返回结果?一步步排查
你说table1和table2行差10条,但关联查不到数据,大概率是这几个原因,挨个试试:
先查关联字段的匹配度:首先确认你用的关联条件是不是有坑——比如字段类型不匹配(一个是字符串一个是数字)、或者字段里藏了空格/大小写差异。举个例子,先试试给关联字段加
TRIM()去掉两边空格再查:SELECT * FROM table1 t1 JOIN table2 t2 ON TRIM(t1.your_join_column) = TRIM(t2.your_join_column);要是DB2里大小写敏感,还可以统一转成大写/小写再匹配:
UPPER(t1.col) = UPPER(t2.col)。排查NULL值的坑:SQL里
NULL = NULL是不成立的,所以如果关联字段有NULL,这些行根本不会匹配。先查下两个表关联字段的NULL数量:-- 查table1关联字段的NULL数 SELECT COUNT(*) FROM table1 WHERE your_join_column IS NULL; -- 查table2关联字段的NULL数 SELECT COUNT(*) FROM table2 WHERE your_join_column IS NULL;要是有NULL,要么过滤掉(加
WHERE your_join_column IS NOT NULL),要么用IS NOT DISTINCT FROM(DB2全版本支持,SQL Server 2022及以上支持)来关联,这个运算符会把NULL视为相等:SELECT * FROM table1 t1 JOIN table2 t2 ON t1.your_join_column IS NOT DISTINCT FROM t2.your_join_column;确认两个表有没有交集:最坏的可能是两个表的关联字段完全没有共同值,先查个交集验证下:
SELECT DISTINCT t1.your_join_column FROM table1 t1 WHERE EXISTS (SELECT 1 FROM table2 t2 WHERE t2.your_join_column = t1.your_join_column);要是这个查询没结果,那说明两个表的关联字段确实没重叠,自然关联查不到数据。
二、查找table1的重复行?两种场景都给你搞定
找重复行的核心就是分组统计,揪出出现次数大于1的组,分两种情况:
场景1:单个字段重复(比如id重复)
先找出哪些值重复了,再看对应的完整行:
-- 第一步:找出重复的字段值和重复次数 SELECT your_dup_column, COUNT(*) AS duplicate_times FROM table1 GROUP BY your_dup_column HAVING COUNT(*) > 1; -- 第二步:查看这些重复值对应的所有行 SELECT t1.* FROM table1 t1 INNER JOIN ( SELECT your_dup_column FROM table1 GROUP BY your_dup_column HAVING COUNT(*) > 1 ) t2 ON t1.your_dup_column = t2.your_dup_column ORDER BY t1.your_dup_column;
场景2:多个字段组合重复(比如name+phone一起重复才算)
如果是多个字段组合起来重复才算,只要把GROUP BY和关联条件改成多个字段就行:
-- 找出重复的字段组合和次数 SELECT col1, col2, COUNT(*) AS duplicate_times FROM table1 GROUP BY col1, col2 HAVING COUNT(*) > 1; -- 查看完整的重复行 SELECT t1.* FROM table1 t1 INNER JOIN ( SELECT col1, col2 FROM table1 GROUP BY col1, col2 HAVING COUNT(*) > 1 ) t2 ON t1.col1 = t2.col1 AND t1.col2 = t2.col2 ORDER BY t1.col1, t1.col2;
额外小技巧(SQL Server专属)
SQL Server可以用窗口函数ROW_NUMBER()给重复行标记序号,方便区分哪条是原始行,哪条是重复行:
SELECT *, ROW_NUMBER() OVER(PARTITION BY your_dup_column ORDER BY (SELECT NULL)) AS row_number FROM table1 ORDER BY your_dup_column;
这里row_number大于1的就是重复行啦。
内容的提问来源于stack exchange,提问作者user7463647

