如何比较两个相同表中的行并返回缺失行的结果集?

时间:2010-10-20 01:56:56

标签: sql mysql

我查看了所有相关问题,但没有一个完全符合我的要求。我有两个结构相同的表(id,VoucherNbr,BalanceInit) - 一个来自我们当前的生产系统(tableA),另一个来自客户的遗留系统(tableB)。表A具有记录a,b,c,d,e(例如),并且表B具有a,b,c,d,e,f,g。表B将始终具有表A中存在的所有值,但也具有额外的行。我需要返回一个结果集,其中包含表B中表A中不存在的所有行(f和g,使用示例。)我该怎么做?

编辑:

表A

ID | VoucherNbr         | BalanceInit
=============================================
1  | 1111111111111111   | 25.00
2  | 2222222222222222   | 50.00
3  | 3333333333333333   | 10.00

表B

ID | VoucherNbr         | BalanceInit
=============================================
15 | 1111111111111111   | 25.00
17 | 1212121212121212   | 15.00
22 | 2222222222222222   | 50.00
34 | 3333333333333333   | 25.00
41 | 3232323232323232   | 75.00

我需要返回的是一个结果集,其中只包含表A中不存在的行,其中它是VoucherNbr字段中不存在的值,而不是ID字段。

ID | VoucherNbr         | BalanceInit
=============================================
17 | 1212121212121212   | 15.00
41 | 3232323232323232   | 75.00

3 个答案:

答案 0 :(得分:9)

某些数据库使用SUBTRACT或MINUS操作直接提供此功能。 MySQL似乎没有任何此类操作。

我可能会这样做:

SELECT  B.id, B.voucherNbr, B.balanceInit FROM tableB B
   WHERE NOT EXISTS 
     (SELECT * FROM tableA A 
      WHERE A.voucherNbr = B.voucherNbr AND A.balanceInit = B.balanceInit)

但是,这里有几个其他MySQL解决方案(我用谷歌搜索)你可以测试速度:

SELECT  id, voucherNbr, balanceInit FROM tableB 
   WHERE (voucherNbr, balanceInit) NOT IN 
      (SELECT voucherNbr, balanceInit FROM tableA);

SELECT  id, voucherNbr, balanceInit
   FROM tableB LEFT JOIN tableA USING (voucherNbr, balanceInit)
      WHERE tableA.voucherNbr IS NULL

老实说,如果执行时间相似或更好,我比第一个Google搜索解决方案更好。

注意:我已经从原来的答案中修改了这些内容,以反映您在另一个答案的评论中说明两个表中的ID不同。

答案 1 :(得分:1)

注意:假设id是两个表的PK。

SELECT B.* FROM TableB B 
LEFT OUTER JOIN TableA A
ON B.id = A.id
WHERE A.id IS NULL

编辑:基于OP的进一步提交,因为两个表中相同行的Id不同,假设匹配条件基于比较2列值

SELECT B.* FROM TableB B 
LEFT OUTER JOIN TableA A
ON B.VoucherNbr = A.VoucherNbr
AND B.BalanceInit = A.BalanceInit
WHERE A.VoucherNbr IS NULL 

EDIT2:如果只有凭证号码本身就足够了,那么也可以丢弃balanceInit

SELECT B.* FROM TableB B 
LEFT OUTER JOIN TableA A
ON B.VoucherNbr = A.VoucherNbr
WHERE A.VoucherNbr IS NULL 

答案 2 :(得分:0)

您可以使用 INTERSECT stament

SELECT * FROM tableA 
INTERSECT 
SELECT * FROM tableB 

-EXCEPT返回左侧查询中的任何不同值,这些值在右侧查询中也找不到。

-INTERSECT返回INTERSECT操作数左侧和右侧的查询返回的任何不同值。

http://msdn.microsoft.com/en-us/library/ms188055.aspx