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

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

При разработке отчетов или обработок на 1С часто возникает необходимость объединить данные из двух источников. Однако стандартный оператор ОБЪЕДИНИТЬ работает по принципу исключения полностью идентичных строк. Если записи различаются хотя бы в одном реквизите, они все попадут в итоговую выборку. Рассмотрим, как эффективно решить задачу исключения записей второго запроса на основе условий из первого.

Метод 1: Использование левого соединения с проверкой на NULL

Это наиболее профессиональный и производительный способ. Вместо попыток отфильтровать результат уже после объединения, мы заранее отсекаем лишние данные на этапе формирования второго набора. Суть подхода заключается в том, чтобы «присоединить» к данным второй таблицы данные первой и оставить только те записи, для которых не нашлось пары в первой таблице.

Рассмотрим пример кода для реализации этой логики:


ВЫБРАТЬ 
    Таб1.Регистратор1, 
    Таб1.Рекв2 
ИЗ 
    Таблица1 КАК Таб1

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ 
    Таб2.Регистратор1, 
    Таб2.Рекв2 
ИЗ 
    Таблица2 КАК Таб2
    ЛЕВОЕ СОЕДИНЕНИЕ Таблица1 КАК Таб1 
    ПО Таб2.Регистратор1 = Таб1.Регистратор1
ГДЕ 
    Таб1.Регистратор1 ЕСТЬ NULL

Почему это работает? Левое соединение пытается найти соответствие. Если запись с таким же значением Регистратор1 существует в Таблица1, то поля из Таб1 будут заполнены. Если же записи нет, то поля из Таб1 примут значение NULL. Условие ГДЕ ... ЕСТЬ NULL отбирает только те строки из Таблица2, которые уникальны относительно Таблица1.

Метод 2: Использование конструкции НЕ В

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

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


ВЫБРАТЬ 
    Поле1, Поле2 
ИЗ Таблица1 

ОБЪЕДИНИТЬ 

ВЫБРАТЬ 
    Поле1, Поле2 
ИЗ Таблица2 
ГДЕ НЕ Поле1 В (ВЫБРАТЬ Т.Поле1 ИЗ Таблица1 КАК Т)

Обратите внимание: данный метод удобен, но при работе с огромными массивами данных может требовать больше ресурсов сервера, чем ЛЕВОЕ СОЕДИНЕНИЕ, так как подзапрос в условии ГДЕ может выполняться для каждой проверяемой строки.

Метод 3: Использование временных таблиц

Для сложных задач, где требуется высокая производительность, лучше всего использовать МенеджерВременныхТаблиц. Это позволяет сначала подготовить данные, проиндексировать их и только потом выполнять основное соединение. Это «золотой стандарт» разработки в 1С.

Рассмотрим алгоритм действий:

  1. Выбираем данные из первой таблицы и помещаем их во временную таблицу с помощью инструкции ПОМЕСТИТЬ.
  2. В основном запросе обращаемся к этой временной таблице, используя ее как справочник для фильтрации.
  3. Индексация по ключевым полям во временной таблице значительно ускорит поиск соответствий.

Пример реализации:


ВЫБРАТЬ 
    Таблица1.Ссылка 
ПОМЕСТИТЬ ВремТаблица 
ИЗ Справочник.Номенклатура КАК Таблица1;

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

Важные советы по оптимизации

Чтобы ваш код работал быстро и не вызывал нареканий системы, примите к сведению следующие рекомендации:

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

← На главную