SQL Server:对比两张表所有值及基于TipoComponenteID获取目标结果
嘿,这两个问题都是SQL Server开发里高频遇到的场景,我给你整理了几种实用的解决方案,都是平时干活常用的:
1. 如何在SQL Server中对比两张表的所有数据值
下面是几种不同场景下的方法,你可以根据自己的需求选:
方法一:用EXCEPT + UNION ALL快速找所有差异行
这个方法适合两张表列结构完全一致(列数、数据类型、顺序都匹配)的情况,能直接找出两张表中所有不重复的差异行:-- 找出TableA有但TableB没有的行 SELECT * FROM TableA EXCEPT SELECT * FROM TableB UNION ALL -- 找出TableB有但TableA没有的行 SELECT * FROM TableB EXCEPT SELECT * FROM TableA注意:如果要考虑重复行的数量差异(比如TableA某行出现3次,TableB出现2次),这个方法就不适用了,得用分组统计的方式。
方法二:LEFT/RIGHT JOIN定位单方向差异
如果你只想看某一张表中存在但另一张表没有的行,用连接+IS NULL的方式更直观,比如找TableA中不在TableB的行:SELECT A.* FROM TableA A LEFT JOIN TableB B ON A.PrimaryKey = B.PrimaryKey -- 优先用主键关联,列少的话也可以写所有列相等的条件 WHERE B.PrimaryKey IS NULL把LEFT换成RIGHT就能反过来找TableB独有的行。
方法三:用校验和/哈希值快速对比行
如果表的列很多,写一堆相等条件太麻烦,可以用校验和函数计算每行的唯一标识,再对比:-- 用HASHBYTES更准确(注意处理NULL值) SELECT HASHBYTES('SHA2_256', CONCAT(ISNULL(Col1, ''), ISNULL(Col2, ''), ...)) AS RowHash, * FROM TableA EXCEPT SELECT HASHBYTES('SHA2_256', CONCAT(ISNULL(Col1, ''), ISNULL(Col2, ''), ...)) AS RowHash, * FROM TableB注意:CHECKSUM偶尔会出现不同行得到相同值的碰撞情况,用SHA2_256哈希的话几乎不会有这个问题,但计算速度会慢一点。
2. 如何利用包含TipoComponenteID1、TipoComponenteID2的两张表得到指定结果
因为你没明确说“指定结果”具体是什么,我列几个最常见的业务场景,你可以按需调整:
场景1:获取两张表中ID匹配的关联数据
如果要把两张表中TipoComponenteID1和TipoComponenteID2相等的行合并查询,用内连接:
SELECT A.*, B.* FROM TableA A INNER JOIN TableB B ON A.TipoComponenteID1 = B.TipoComponenteID2
场景2:找出某张表中ID不在另一张表的行
比如找TableA里TipoComponenteID1在TableB的TipoComponenteID2中不存在的数据:
SELECT A.* FROM TableA A LEFT JOIN TableB B ON A.TipoComponenteID1 = B.TipoComponenteID2 WHERE B.TipoComponenteID2 IS NULL
场景3:合并两张表的ID列,得到所有唯一ID
如果要汇总两张表的所有组件ID并去重:
SELECT TipoComponenteID1 AS ComponentID FROM TableA UNION SELECT TipoComponenteID2 AS ComponentID FROM TableB
如果不需要去重,把UNION换成UNION ALL就行。
场景4:统计每个ID在两张表中的出现次数
要知道每个组件ID分别在两张表中出现了多少次,可以用联合查询+分组统计:
SELECT ComponentID, COUNT(CASE WHEN Source = 'TableA' THEN 1 END) AS CountInTableA, COUNT(CASE WHEN Source = 'TableB' THEN 1 END) AS CountInTableB FROM ( SELECT TipoComponenteID1 AS ComponentID, 'TableA' AS Source FROM TableA UNION ALL SELECT TipoComponenteID2 AS ComponentID, 'TableB' AS Source FROM TableB ) AS CombinedData GROUP BY ComponentID
内容的提问来源于stack exchange,提问作者foluis

