#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;