Как проверить, что две таблицы имеют одинаковые данные? - PullRequest
24 голосов
/ 25 января 2010

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

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

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

Ответы [ 7 ]

33 голосов
/ 25 января 2010

Вы можете просто использовать ТАБЛИЦА КОНТРОЛЬНОЙ СУММЫ и сравнить результаты. Вы можете даже изменить таблицу , чтобы включить контрольные суммы в реальном времени, чтобы они были постоянно доступны.

CHECKSUM TABLE original_table, backup_table;

Для таблиц не требуется первичный ключ.

19 голосов
/ 13 декабря 2012
SELECT * FROM Table1
UNION
SELECT * FROM Table2

Если вы получаете записи, превышающие любую из двух таблиц, они не имеют одинаковых данных.

16 голосов
/ 25 января 2010

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

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

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

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

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

Приложив немного усилий, вы можете сделать это за один запрос, используя полное внешнее объединение. Будьте осторожны с внешними объединениями, так как они ведут себя по-разному в разных механизмах SQL. Предикаты, помещенные в предложение where вместо предложения join, иногда могут превратить ваше внешнее соединение во внутреннее соединение.

1 голос
/ 21 мая 2015

Попробуйте сравнить две таблицы следующим образом:

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;
1 голос
/ 25 января 2010
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

Полное объединение / проверка на ноль должны охватывать добавления или удаления, а также изменения.

  • backup.id имеет значение null = сложение
  • original.id имеет значение null = удаление
  • none null = изменить
0 голосов
/ 30 января 2017

Пожалуйста, попробуйте следующий метод для определения того, являются ли две таблицы абсолютно одинаковыми, когда нет первичного ключа любого типа и нет дублирующихся строк в таблице, используя следующую логику:

Шаг 1 - Проверка на наличие повторяющихся строк в TABLEA

Если ВЫБРАТЬ ОТЛИЧИТЬ * ОТ ТАБЛИЦЫ

имеет столько же строк, сколько и

ВЫБРАТЬ * ИЗ ТАБЛИЦЫ

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

Шаг 2 - Проверка на наличие повторяющихся строк на TABLEB

Если ВЫБРАТЬ DISTINCT * ОТ ТАБЛИЦЫ

имеет столько же строк, сколько и

ВЫБРАТЬ * ИЗ ТАБЛИЦЫ

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

Шаг 3 - ПОДКЛЮЧИТЕ ВНУТРЕННЮЮ ТАБЛИЦУ к 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)

Обратная связь приветствуется!

0 голосов
/ 30 апреля 2010

Для более ленивого или более не склонного к SQL разработчика, работающего с MS SQL Server, я бы порекомендовал SQL Delta (www.sqldelta.com) для этой и любой другой работы типа diff-database. Он имеет отличный графический интерфейс, быстрый и точный и может различать все объекты базы данных, генерировать и запускать необходимые сценарии изменений, синхронизировать целые базы данных. Это следующая лучшая вещь для DBA; -)

Я думаю, что в RedGate есть аналогичный инструмент под названием SQL Compare. Я считаю, некоторые выпуски последней версии Visual Studio (2010) также содержат очень похожий инструмент.

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