我有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,名称,号码,电子邮件和几个标志以及其他信息)。
执行此操作是否有最高性能的解决方案,或者我必须将每个列与新查询进行比较..?
答案 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视为与非空值不同。