SQLite找到两个表之间的差异

时间:2014-08-13 21:17:44

标签: mysql sql sqlite

我有两个表都包含id(primary key)contact_idname。 我想找出两个表之间的差异。因此,如果table A中的一条记录与table B不同,则sql查询应该找到它。例如,在下面的代码中,('2','test2')没有出现在表B中。因此,记录('2','test2')是两个表之间的差异。但是,我们可能会遇到相反的情况,例如table Btable A中出现一条记录。或者两个表中的记录contact_id可能相同,但name字段可能不同。在这种情况下,还应返回不同的记录。我已经这样做了,但它似乎并不适用于所有情况。如何让它适用于所有情况?

CREATE TABLE A 
    (
     id int auto_increment primary key, 
     contact_id int(20),
      name varchar(20)
    );

CREATE TABLE B 
    (
     id int auto_increment primary key, 
     contact_id int(20),
      name varchar(20)
    );

INSERT INTO A
(contact_id,name)
VALUES
('1','test1'),
('2','test2');

INSERT INTO B
(contact_id,name)
VALUES
('1','test1');

查询:

SELECT * FROM A
    EXCEPT
    SELECT * FROM B
UNION ALL
   SELECT * FROM B
    EXCEPT
    SELECT * FROM A

这是sqlfiddle: http://sqlfiddle.com/#!5/f7f45/9 并在弹出屏幕中选择取消。

2 个答案:

答案 0 :(得分:1)

左边加入a到b,其中b为null,得到什么,但不是b,左边的连接b到a,其中a为空,得到b中的什么而不是a。

select 'in a but not b', a.* 
from a left join b on a.contact_id = b.contact_ID
where b.contact_ID is null
union all
select'in b but not a', b.* 
from b left join a on a.contact_id = b.contact_ID
where a.contact_ID is null

我在一个字段中表示记录的起源,因为它在联合结果中不会显而易见。如果你感兴趣,第三个查询检查记录在a和b中的位置,但是ID有不同的值......同样的想法,只是内连接:

select a.*,b.*
from a inner join b on a.contact_id = b.contact_ID
where a.name <> b.name

答案 1 :(得分:1)

EXCEPT绑定不比UNION ALL强(并且缩进查询不会改变它),因此数据库将在第二个EXCEPT之前执行UNION ALL。

您必须将两个EXCEPT查询移动到子查询中,以确保最后执行UNION ALL:

SELECT * FROM (SELECT * FROM A
               EXCEPT
               SELECT * FROM B)
UNION ALL
SELECT * FROM (SELECT * FROM B
               EXCEPT
               SELECT * FROM A)