MySQL选择2个表之间的所有差异?

时间:2011-06-24 17:06:35

标签: mysql sql

我有3个表,'旧','新'和'结果'表(来自电话簿数据库),它们具有相同的结构和几乎相同的条目。

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

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

从这个'新'表中我想选择与'old'表不同的所有行,结果将是:

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

包括所有已更改数据的条目以及未出现在“旧”表格中的所有条目...

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

执行此操作是否有最高性能的解决方案,或者我必须将每个列与新查询进行比较..?

3 个答案:

答案 0 :(得分:4)

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

更新我对包含所有已更改数据的条目以及未出现在“旧”表中的所有条目感到有点困惑...所以我添加了where并修改了join子句

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
  ...)

答案 1 :(得分: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...))

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

答案 2 :(得分: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&lt;&gt; n.name)而不是(o.name = n.name),则不能正确地将NULL视为与非空值不同。