MySQL Выбрать все различия между 2 таблицами? - PullRequest
1 голос
/ 24 июня 2011

У меня есть 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  |

Из этого«Новая» таблица Я хотел бы выбрать все строки, которые отличаются от «старой» таблицы, поэтому результат будет:

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

, включая все записи, которые изменили данные, плюс все записи, которые непоявляются в «старой» таблице ...

Мало того, чтобы сделать ее более сложной, в этих таблицах около 10 столбцов (включая идентификатор, имя, номер, адрес электронной почты, несколько флагов и другую информацию).

Есть ли наиболее эффективное решение для этого или мне придется сравнивать каждый столбец с новым запросом ..?

Ответы [ 3 ]

4 голосов
/ 24 июня 2011

Вам нужно будет сделать сравнение старых записей на предмет корректности, но я думаю, что это наиболее прямолинейное решение.

Обновление Я был немного смущен включением всех записейкоторые изменили данные плюс все записи, которые не отображаются в «старой» таблице ... Поэтому я добавил оператор 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 голос
/ 24 июня 2011
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 голосов
/ 24 июня 2011

Предполагая, что идентификаторы должны совпадать, чтобы сделать сравнения законными:

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) вместо not (o.name = n.name), вы не будете правильно считать NULL отличными от ненулевых.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...