SQL Server中如何获取两张表同标识记录的差值返回结果
解决方案
问题原因:EXCEPT不适用的本质
EXCEPT 运算符的逻辑是返回存在于左表但不存在于右表的不重复记录,只要某条内容的记录在右表出现过哪怕1次,左表中所有相同内容的该类记录都会被直接排除,自然无法实现按条数做差值的需求。
实现方法(支持窗口函数的数据库通用:MySQL 8.0+/PostgreSQL/SQL Server等)
给两张表的同类型记录增加组内行号,再排除掉内容、行号都匹配的记录,剩下的左表记录就是你需要的结果:
-- 给A表符合条件的记录加行号:相同内容的记录按顺序编号 WITH a_with_rn AS ( SELECT *, ROW_NUMBER() OVER( PARTITION BY doc_type, 列1, 列2 -- 此处替换为你判断两条记录相同的所有匹配字段 ORDER BY 1 ) AS row_num FROM 表A WHERE doc_type = 'Faktura zakupu' ), -- 给B表符合条件的记录加行号,规则和A表完全一致 b_with_rn AS ( SELECT *, ROW_NUMBER() OVER( PARTITION BY doc_type, 列1, 列2 -- 和A表的PARTITION BY字段完全对应 ORDER BY 1 ) AS row_num FROM 表B WHERE doc_type = 'Faktura zakupu' ) -- 左连接后取B表没有匹配到的A表记录,就是差值条数的结果 SELECT a.* FROM a_with_rn a LEFT JOIN b_with_rn b ON a.doc_type = b.doc_type AND a.列1 = b.列1 AND a.列2 = b.列2 -- 所有匹配字段都要加关联条件 AND a.row_num = b.row_num WHERE b.doc_type IS NULL;
举个实际逻辑示例:如果A表有3条完全一致的'Faktura zakupu'记录,B表有1条相同内容的记录,那么A表的行号是1、2、3,B表的行号是1,关联后只有行号1的记录会匹配成功被排除,最终剩下行号2、3的两条记录,刚好符合3-1=2的计数要求。
示例场景匹配效果

如果你的数据库是不支持窗口函数的老版本(比如MySQL 5.x),可以用用户变量模拟行号实现相同逻辑,核心思路和上面的方案完全一致。
内容的提问来源于stack exchange,提问作者Falcon
相关产品推荐
相关产品推荐

