Как проверить, имеют ли две таблицы одинаковые данные?
По сути, у нас есть одна таблица (original table
), и она резервируется в другую таблицу (backup table
); таким образом, две таблицы имеют абсолютно одинаковую схему.
В начале обе таблицы (original table
и backup table
) содержат абсолютно одинаковый набор данных. Через некоторое время по какой-то причине мне нужно проверить, изменился ли набор данных в original table
.
Для этого мне нужно сравнить набор данных в original table
с backup table
.
Допустим, у original table
есть следующая схема:
create table LemmasMapping (
lemma1 int,
lemma2 int,
index ix_lemma1 using btree (lemma1),
index ix_lemma2 using btree (lemma2)
)
Как я могу добиться сравнения наборов данных?
Обновление: таблица не имеет первичного ключа. Он просто хранит сопоставления между двумя идентификаторами.
Ответы
Ответ 1
Я бы написал три запроса.
Внутреннее объединение для выбора строк, в которых первичный ключ существует в обеих таблицах, но есть разница в значении одного или нескольких других столбцов. Это позволит подобрать измененные строки в оригинале.
Левое внешнее объединение, чтобы выбрать строки, которые находятся в исходных таблицах, но не в резервной таблице (то есть строка в исходном имеет первичный ключ, который не существует в резервной копии). Это вернет строки, вставленные в оригинал.
Правое внешнее соединение для выбора строк в резервной копии, которых больше нет в оригинале. Это вернет строки, которые были удалены из оригинала.
Вы можете объединить три запроса вместе, чтобы вернуть один набор результатов. Если вы это сделаете, вам нужно будет добавить столбец, чтобы указать тип строки (обновлен, вставлен или удален).
Приложив немного усилий, вы можете сделать это за один запрос, используя full outer join. Будьте осторожны с внешними объединениями, так как они ведут себя по-разному в разных механизмах SQL. Предикаты, помещенные в предложение where вместо предложения join, иногда могут превратить ваше внешнее соединение во inner join.
Ответ 2
Вы можете просто использовать CHECKSUM TABLE и сравнить результаты. Вы можете даже изменить таблицу, чтобы включить контрольные суммы в реальном времени, чтобы они были постоянно доступны.
CHECKSUM TABLE original_table, backup_table;
Это не требует, чтобы в таблицах был первичный ключ.
Ответ 3
SELECT * FROM Table1
UNION
SELECT * FROM Table2
Если вы получаете записи больше, чем любая из двух таблиц, они не имеют одинаковых данных.
Ответ 4
select count(*)
from lemmas as original_table
full join backup_table using (lemma_id)
where backup_table.lemma_id is null
or original_table.lemma_id is null
or original_table.lemma != backup_table.lemma
Полное соединение/проверка для null должно охватывать дополнения или удаления, а также изменения.
- backup.id = null = дополнение
- original.id = null = удаление
- ни null = изменить
Ответ 5
Попробуйте сравнить две таблицы:
SELECT 'different' FROM DUAL WHERE EXISTS(
SELECT * FROM (
SELECT /*DISTINCT*/ +1 AS chk,a.c1,a.c2,a.c3 FROM a
UNION ALL
SELECT /*DISTINCT*/ +1 AS chk,b.c1,b.c2,b.c3 FROM b
) c
GROUP BY c1,c2,c3
HAVING SUM(chk)<>2
)
UNION SELECT 'equal' FROM DUAL
LIMIT 1;
Ответ 6
Для более ленивого или более несклонного разработчика, работающего с MS SQL Server, я бы рекомендовал SQL Delta (www.sqldelta.com) для этой и любой другой работы типа базы данных. Он имеет большой графический интерфейс, быстрый и точный и может различать все объекты базы данных, создавать и запускать необходимые сценарии изменений, синхронизировать целые базы данных. Это лучшая вещь для администратора базы данных: -)
Я думаю, что есть аналогичный инструмент, доступный RedGate под названием SQL Compare. Я считаю, что некоторые выпуски последней версии Visual Studio (2010) также включают очень похожий инструмент.
Ответ 7
Попробуйте использовать следующий метод для определения того, являются ли две таблицы одинаковыми, если нет первичного ключа какого-либо типа, и в таблице нет повторяющихся строк, используя следующую логику:
Шаг 1 - Тест для повторяющихся строк на TABLEA
Если SELECT DISTINCT * FROM TABLEA
имеет тот же самый счетчик строк, что и
SELECT * FROM TABLEA
перейдите к следующему шагу, иначе вы не сможете использовать этот метод...
Шаг 2 - Тест для повторяющихся строк на TABLEB
Если SELECT DISTINCT * FROM TABLEB
имеет тот же самый счетчик строк, что и
SELECT * FROM TABLEB
перейдите к следующему шагу, иначе вы не сможете использовать этот метод...
Шаг 3 - INNER JOIN TABLEA в TABLEB в каждом столбце
Если количество строк в нижеприведенном запросе имеет тот же подсчет строк, что и количество строк из шагов 1 и 2, то таблицы одинаковы:
SELECT
*
FROM
TABLEA
INNER JOIN TABLEA ON
TABLEA.column1 = TABLEB.column1
AND TABLEA.column2 = TABLEB.column2
AND TABLEA.column3 = TABLEB.column3
--etc...for every column
Обратите внимание, что этот метод не обязательно проверяет разные типы данных и, вероятно, не будет работать на несовместимых типах данных (например, VARBINARY)
Обратная связь приветствуем!
Ответ 8
1: Сначала получите счет для таблиц C1 и C2. C1 и C2 должны быть равны.
C1 и C2 можно получить по следующему запросу
select count(*) from table1
если C1 и C2 не равны, то таблицы не идентичны.
2: Найти различный счетчик для таблиц DC1 и DC2. DC1 и DC2 должны быть равны. Количество различных записей можно найти с помощью следующего запроса:
select count(*) from (select distinct * from table1)
если DC1 и DC2 не равны, таблицы не идентичны.
3: Теперь получите количество записей, полученных путем объединения двух таблиц. Пусть это будет U. Используйте следующий запрос, чтобы получить количество записей в объединении из 2 таблиц:
SELECT count (*)
FROM
(SELECT *
FROM table1
UNION
SELECT *
FROM table2)
Можно сказать, что данные в 2 таблицах идентичны, если различное количество для 2 таблиц равно количеству записей, полученных путем объединения двух таблиц. т.е.
DC1 = U и DC2 = U