Какой тип join лучше применять для сравнения таблиц?
Что проверяют
Умеете ли вы превратить «сравнить таблицы» в конкретную задачу: найти лишние записи, недостающие или расхождения в значениях. Правильный ответ начинается с уточнения цели, а не с названия соединения. Следом обычно дают две выгрузки и просят найти расхождения.
Как отвечать
Под каждую цель свой инструмент:
- полная сверка двух источников:
FULL OUTER JOINпо ключу. Он возвращает строки из обеих таблиц, и каждую можно разметить: есть только в A (b.id IS NULL), только в B (a.id IS NULL), есть в обеих, но значения различаются; - что есть в A и нет в B:
LEFT JOIN ... WHERE b.id IS NULLилиNOT EXISTS; - совпадение целых строк:
EXCEPTв обе стороны,A EXCEPT BиB EXCEPT A. Удобно, когда ключа нет или сравниваются все колонки; - только общие записи:
INNER JOIN. Для сравнения он годится хуже всего, потому что прячет как раз расхождения.
Значения внутри найденных пар сравнивайте через a.amount IS DISTINCT FROM b.amount. Обычное <> при NULL с одной стороны возвращает неизвестность, и расхождение не попадёт в отчёт. В MySQL для этого есть NOT (a <=> b), а FULL OUTER JOIN там нет, его собирают через UNION левого и правого соединения.
Перед сверкой проверьте, что ключ уникален: GROUP BY id HAVING COUNT(*) > 1. Иначе соединение размножит строки, и отчёт покажет расхождения, которых нет. И приведите ключи к одному виду: тип, регистр, пробелы по краям, ведущие нули.
Если данные в Excel, логика та же: ВПР или ПРОСМОТРX это левое соединение, а для полной сверки нужен поиск в обе стороны.
Где спотыкаются
Отвечают «INNER JOIN» без уточнений. Для сравнения это худший выбор: записи без пары, то есть главные расхождения, в результат не попадают.
Сравнивают значения через = и <>, забывая про NULL. Строка, где в одной таблице сумма есть, а в другой пусто, молча выпадает из отчёта о расхождениях.
Не проверяют дубли ключа и приносят отчёт о тысяче расхождений, которые на самом деле появились от размножения строк.