开发者

MySQL Select all differences between 2 tables?

I have 3 tables, 'ol开发者_Go百科d', 'new' and a 'result' table (from a phonebook database), they have the same structure and nearly the same entries.

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  |

From this 'new' table I would like to select all rows that are different from the 'old' table, so the result would be:

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

including all entries that have changed data plus all entries that don't appear in 'old' table...

Not only to make it more complicated, there are about 10 columns in those tables (including ID, name, number, email and several flags and other info).

Is there any most performant solution for doing this or will I have to compare each column with a new query..?


You'll have to do some comparison on the old records for correctness but I think this is the most straight forward solution.

Update I was a little confused about icluding all entries that have changed data plus all entries that don't appear in 'old' table... So I added the where and modified the join clause

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


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

That should pull up any records in the new table where at least one its fields differs from the equivalent record in the old table.


Assuming the IDs must match up in order to make the comparisons legitimate:

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

Note, this solution handles the case where some of the fields can be NULL. If you use (o.name <> n.name) instead of not (o.name = n.name) you won't correctly consider NULLs to be different from non-nulls.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜