2011-06-24 38 views
1

我有3个表,'旧','新'和'结果'表(来自电话簿数据库),它们具有相同的结构和几乎相同的条目。MySQL选择2个表之间的所有区别?

old: 
ID | name    | number | email | ... 
----+--------------------+--------+-------+----- 
1 | foo    | 123 | ... 
2 | bar    | 456 | 
3 | entrry with typo || 
4 | John Doe   | 123345 | 

new: 
ID | name    | number | email | ... 
----+--------------------+--------+-------+----- 
1 | foo    | 123 | ... 
2 | bar    | 456 | 
3 | entry without typo || 
4 | John Doe   | 12345 | 
5 | newly added entry | 09876 | 

从这个“新”的表,我想选择是从“老”表中的不同都行,这样的结果将是:

result: 
ID | name    | number | email | ... 
----+--------------------+--------+-------+----- 
3 | entry without typo || ... 
4 | John Doe   | 12345 | 
5 | newly added entry | 09876 | 

包括已更改数据的所有条目加上所有没有出现在“旧”表中的条目...

不仅使它更复杂,这些表中大约有10列(包括ID,名称,号码,电子邮件和几个标志以及其他信息)。

是否有任何最高性能的解决方案这样做,或者我将不得不比较每个列与新的查询..?

+0

一个高质量的工作将需要你手工完成 - 'name'/etc不是一个可靠的方法来确定什么是或不存在,或已经改变... –

回答

4

您必须对旧记录进行正确性比较,但我认为这是最直接的解决方案。

更新我有点困惑icluding已更改数据的所有条目加上没有出现在“老”表......所有条目所以我加入了其中,并修改了加入条款

insert into result (id, name, number, email, ...) 
select new.id, new.name, new.number, new.email, ... 
from new 
LEFT JOIN old 
ON new.ID = old.id 
WHERE 
old.ID is null 
OR 
(new.name <> old.name 
    or 
    new.number <> old.number 
    or 
    new.email <> new.email 
    ...) 
+0

洙非常感谢,我仍然没有与JOIN语法相处不足 - .- – flo

1
SELECT new.* 
FROM new 
JOIN old ON new.id = old.id 
WHERE (CONCAT(new.ID,new.name,new.number,etc...) <> CONCAT(old.ID,old.name,old.number,etc...)) 

这应该拉起新表中的任何记录,其中至少有一个字段与旧表中的等效记录不同。

+0

我首先想到的是比较两行的校验和,但是我没有找到用于做的函数,所以我认为CONCAT()也适用。 – flo

0

假设ID必须为了使比较合理的热身赛:

select n.* 
from new n 
left join old o on o.id = n.id 
where o.id is null 
    or not (
    and o.name = n.name 
    and o.number = n.number 
    and o.email = n.email 
    and ...) 

注意,该解决方案处理这样一些字段可以为NULL的情况。如果使用(o.name <> n.name)而不是(o.name = n.name),则不会正确地将NULL视为与非空值不同。