Подтвердить что ты не робот

Как проверить, имеют ли две таблицы одинаковые данные?

По сути, у нас есть одна таблица (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)
)

Как я могу добиться сравнения наборов данных?

Обновление: таблица не имеет первичного ключа. Он просто хранит сопоставления между двумя идентификаторами.

4b9b3361

Ответ 1

Я бы написал три запроса.

  1. Внутреннее объединение для выбора строк, в которых первичный ключ существует в обеих таблицах, но есть разница в значении одного или нескольких других столбцов. Это позволит подобрать измененные строки в оригинале.

  2. Левое внешнее объединение, чтобы выбрать строки, которые находятся в исходных таблицах, но не в резервной таблице (то есть строка в исходном имеет первичный ключ, который не существует в резервной копии). Это вернет строки, вставленные в оригинал.

  3. Правое внешнее соединение для выбора строк в резервной копии, которых больше нет в оригинале. Это вернет строки, которые были удалены из оригинала.

Вы можете объединить три запроса вместе, чтобы вернуть один набор результатов. Если вы это сделаете, вам нужно будет добавить столбец, чтобы указать тип строки (обновлен, вставлен или удален).

Приложив немного усилий, вы можете сделать это за один запрос, используя 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