Как в запросе 1С сравнить две таблицы и вывести различающиеся строки?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

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

Способ 1. Полное внешнее соединение и проверка на NULL

Разберем классический вариант поиска несовпадающих записей с помощью конструкции ПОЛНОЕ СОЕДИНЕНИЕ. Этот способ подходит для поиска строк, которые присутствуют в одной таблице, но отсутствуют в другой по заданным ключевым полям.

Проанализируем ситуацию: пусть имеются две таблицы Таблица1 и Таблица2 со схожим набором колонок (касса, тип операции, суммы). Нам необходимо найти записи, которые не сопоставились друг с другом:


ВЫБРАТЬ
    ЕСТЬNULL(Т1.Касса, Т2.Касса) КАК Касса,
    ЕСТЬNULL(Т1.Тип, Т2.Тип) КАК Тип,
    Т1.НомерЧекаККМ КАК Чек1,
    Т2.НомерЧекаККМ КАК Чек2,
    Т1.СуммаНаличными КАК СуммаНал1,
    Т2.СуммаНаличными КАК СуммаНал2
ИЗ
    Таблица1 КАК Т1
    ПОЛНОЕ СОЕДИНЕНИЕ Таблица2 КАК Т2
        ПО Т1.Касса = Т2.Касса
        И Т1.Тип = Т2.Тип
        И Т1.СуммаНаличными = Т2.СуммаНаличными
        И Т1.СуммаБК = Т2.СуммаБК
ГДЕ
    Т1.Касса ЕСТЬ NULL
    ИЛИ Т2.Касса ЕСТЬ NULL
    ИЛИ Т1.НомерЧекаККМ <> Т2.НомерЧекаККМ

Обратим внимание на важную особенность синтаксиса: в условиях фильтрации проверка на отсутствие значения выполняется строго через оператор ЕСТЬ NULL (а не через знак равенства = NULL, так как в SQL и языке запросов 1С любое прямое сравнение с NULL вернет ЛОЖЬ).

Способ 2. Метод весовых коэффициентов (+1 и -1) с группировкой

Разберем по шагам альтернативный и производительный алгоритм, который часто применяется для сравнения больших объемов данных без использования тяжелых внешних соединений.

Суть методики заключается в следующем:

  1. К первой таблице добавляется числовой весовой коэффициент со значением 1.
  2. Ко второй таблице добавляется весовой коэффициент со значением -1.
  3. Таблицы объединяются с помощью конструкции ОБЪЕДИНИТЬ ВСЕ по сравниваемым полям.
  4. Выполняется группировка по всем значимым колонкам с суммированием весового коэффициента.
  5. Строки, у которых итоговая сумма весов равна 0, полностью совпали в обеих таблицах. Строки с весом 1 присутствуют только в первой таблице, а с весом -1 — только во второй.

Посмотрим на пример текста запроса:


ВЫБРАТЬ
    Т.Касса КАК Касса,
    Т.Тип КАК Тип,
    Т.НомерЧекаККМ КАК НомерЧекаККМ,
    Т.СуммаНаличными КАК СуммаНаличными,
    Т.СуммаБК КАК СуммаБК,
    СУММА(Т.Вес) КАК ИтоговыйВес
ИЗ
    (ВЫБРАТЬ
        Т1.Касса КАК Касса,
        Т1.Тип КАК Тип,
        Т1.НомерЧекаККМ КАК НомерЧекаККМ,
        Т1.СуммаНаличными КАК СуммаНаличными,
        Т1.СуммаБК КАК СуммаБК,
        1 КАК Вес
    ИЗ
        Таблица1 КАК Т1
    
    ОБЪЕДИНИТЬ ВСЕ
    
    ВЫБРАТЬ
        Т2.Касса,
        Т2.Тип,
        Т2.НомерЧекаККМ,
        Т2.СуммаНаличными,
        Т2.СуммаБК,
        -1
    ИЗ
        Таблица2 КАК Т2) КАК Т
СГРУППИРОВАТЬ ПО
    Т.Касса,
    Т.Тип,
    Т.НомерЧекаККМ,
    Т.СуммаНаличными,
    Т.СуммаБК
ИМЕЮЩИЕ
    СУММА(Т.Вес) <> 0

Важно: обязательно используйте ОБЪЕДИНИТЬ ВСЕ вместо ОБЪЕДИНИТЬ. Обычное объединение выполняет неявную операцию исключения дубликатов на уровне СУБД, что не только замедляет работу, но и разрушает логику подсчета весов.

Особенности и технические ограничения при сравнении таблиц

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

  1. Типизация колонок в ТаблицеЗначений: если исходные данные передаются во временные таблицы запроса из объекта ТаблицаЗначений, все колонки должны иметь явно объявленный тип данных через ОписаниеТипов. Таблицы с нетипизированными колонками вызовут ошибку при создании временной таблицы.
  2. Строки неограниченной длины: поля неограниченной длины нельзя использовать в секциях ПО, СГРУППИРОВАТЬ ПО и ОБЪЕДИНИТЬ. Для их участия в сравнении примените явное приведение: ВЫРАЗИТЬ(Поле КАК СТРОКА(Длина)).
  3. Индексация полей соединения: для таблиц большого объема при создании временных таблиц критично указывать директиву ИНДЕКСИРОВАТЬ ПО для ключевых полей. Без индекса СУБД выполняет полное сканирование таблицы, что существенно снижает скорость выполнения.
  4. Риск декартова произведения: если во входных таблицах содержатся дубликаты строк по ключевым полям, конструкция ПОЛНОЕ СОЕДИНЕНИЕ может размножить записи (декартово произведение). В таких случаях надежнее использовать метод с весовыми коэффициентами или предварительно группировать таблицы перед соединением.
← На главную