Сравнение двух таблиц в MS Access с использованием SQL

#sql #ms-access

#sql #ms-access

Вопрос:

Я пытаюсь сравнить две таблицы в MS Access с использованием SQL. Каждая таблица имеет два столбца. В TableA меньше строк, чем в TableB, и все в TableA также должно быть в TableB. Я хотел бы проверить, что строки в TableA идентичны соответствующим строкам в TableB, отображая строки, которые не совпадают.

Вот где я столкнулся с проблемой. Я знаю, как сравнивать строки, но не как сравнивать столбцы одновременно. Итак, прямо сейчас, если строки в column1 таблицыa совпадают со строками column1 в TableB, мой запрос будет пустым, даже если некоторые строки в column2 таблицыa не совпадают с некоторыми строками column2 в TableB, и наоборот.

Это мой текущий (общий) код SQL:

 SELECT TableA.*
FROM TableA LEFT JOIN TableB ON TableA.column1 = TableB.column1
WHERE TableA.column1 Is Null;
  

Кто-нибудь знает, как изменить этот код, чтобы проверять оба столбца одновременно? Я хочу, чтобы столбцы рассматривались как один объединенный объект, а не как отдельные.

Спасибо!

Редактировать: я понял, как это сделать. Несколько ответов указали мне правильный путь, но ни один из них не был полным. Это то, что я в итоге сделал. Возможно, это поможет кому-то еще.

 SELECT TableA.*
FROM TableA LEFT JOIN TableB ON TableA.column1 = TableB.column1
    AND TableA.column2 = TableB.column2
WHERE TableA.column1 Is Null OR TableA.column2 Is Null;
  

Комментарии:

1. Отличный ответ, Сэм — будет полезен и мне. Access’ SQL довольно ограничен, но обычным способом я бы сделал это с помощью коррелированного подзапроса: ВЫБЕРИТЕ a.* Из TableA a, ГДЕ НЕ СУЩЕСТВУЕТ (ВЫБЕРИТЕ 1 ИЗ TableB, ГДЕ column1 =.column1 И column2 =.column2)

Ответ №1:

Я полагаю, вам нужно что-то вроде этого:

 SELECT 'Row only in tableA', TableA.column1, TableA.column2
FROM TableA
LEFT JOIN
TableB ON TableA.column1 = TableB.column1 and TableA.column2 = TableB.column2
WHERE TableA.column1 <> TableB.column1 or TableA.column2 <> TableB.column2
union all
SELECT 'Row only in tableB', TableB.column1, TableB.column2
FROM TableB
LEFT JOIN
TableA ON TableA.column1 = TableB.column1 and TableA.column2 = TableB.column2
WHERE TableA.column1 <> TableB.column1 or TableA.column2 <> TableB.column2;
  

Комментарии:

1. @SamIAm что именно не сработало? результаты неверны, синтаксическая ошибка?

2. Я не уверен. Я просто знаю, что он не выявил известных ошибок.

3. Я думаю, что ПРОФСОЮЗ сделал это излишне сложным.

4. @SamIAm union здесь просто для того, чтобы получить оба вида ошибок, я полагаю, ваша проблема из-за неправильного перевода этого шаблона в фактический запрос, проверьте имена таблиц и столбцов

5. Я просто имел в виду, что объединение не было необходимым — я решил проблему, вставив «И» и «ИЛИ». Поскольку я решил проблему, я не собираюсь утруждать себя отладкой этого кода, но все равно спасибо!

Ответ №2:

Это немного непонятно, но звучит так, как будто вы хотите что-то вроде:

 SELECT TableA.*
FROM TableA LEFT JOIN TableB ON TableA.column1 = TableB.column1
WHERE 
    Tableb.column1 Is Null // not found in Tableb
    OR Tablea.Column2 <> Tableb.Column2  // column2 does not match
  

Комментарии:

1. Проблема в том, что он все еще проверяет столбцы по отдельности — мне нужно, чтобы комбинация двух столбцов была идентичной.

Ответ №3:

Я думаю, это должно сработать для вас. Я закодировал это ОЧЕНЬ осторожно, потому что я не знаю, с какими типами данных вы работаете. Что мы пытаемся сделать, так это создать ключ из ВСЕХ столбцов в таблицах и присоединиться к нему. Чтобы выяснить, что в точности совпадает в обеих таблицах:

 SELECT TableA.*
FROM TableA INNER JOIN TableB ON CStr(Nz(TableA.column1, "")) amp; "_" amp; CStr(Nz(TableA.column2, "")) = CStr(Nz(TableB.column1, "")) amp; "_" amp; CStr(Nz(TableB.column2, ""));
  

чтобы выяснить, чего не хватает в TableA:

 SELECT TableB.*
FROM TableA RIGHT JOIN TableB ON CStr(Nz(TableA.column1, "")) amp; "_" amp; CStr(Nz(TableA.column2, "")) = CStr(Nz(TableB.column1, "")) amp; "_" amp; CStr(Nz(TableB.column2, ""))
WHERE TableA.column1 IS NULL;
  

Идея заключается в том, что мы создаем один ключ из всех столбцов, чтобы мы могли работать так, как если бы это было просто внешнее соединение с одним столбцом.

РЕДАКТИРОВАТЬ: Упс, перевернул мои звонки в Nz и CStr.

Комментарии:

1. Почему вы использовали правое соединение вместо левого соединения?

2. @SamIAm: Не беспокойся. Каждое ЛЕВОЕ СОЕДИНЕНИЕ может быть представлено как ПРАВОЕ СОЕДИНЕНИЕ и наоборот. Я сделал это, чтобы мне не пришлось перепечатывать текст.

3. Это я знаю. Но я искал ошибки в таблице A — разве это не показывает ошибки в таблице B?

4. @SamIAm: Кстати, почему я сделал это таким образом, потому что я думал, что вы хотите увидеть строку в B, которой не было в A (отсутствует в A). Во всяком случае, ты сам это понял.

Ответ №4:

 SELECT TableA.*
  FROM TableA 
  LEFT JOIN TableB 
    ON TableA.column1 = TableB.column1
   AND TableA.column2 = TableB.column2
WHERE TableA.column1 Is Null;