Как из одной выборки убрать записи, присутствующие во второй выборке?

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

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

Решение через использование временных таблиц и левого соединения

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

  1. Формирование временных таблиц: Сначала выберем всех производителей из первой и второй таблиц и поместим их во временные таблицы. Это позволит нам работать с ними как с обычными физическими таблицами.
  2. Выполнение левого соединения: Соединим таблицу с компьютерами с таблицей ноутбуков. Суть метода заключается в использовании ЛЕВОЕ СОЕДИНЕНИЕ, которое присоединит к записям первой таблицы все найденные совпадения из второй.
  3. Фильтрация результатов: В строках, для которых не нашлось совпадения во второй таблице, поля из второй таблицы будут иметь значение NULL. Именно эти записи и являются искомой «разностью».

Посмотрим на реализацию этого алгоритма в коде:


ВЫБРАТЬ РАЗЛИЧНЫЕ Оборудование.Производитель 
ПОМЕСТИТЬ ВТКомпьютеры 
ИЗ Справочник.Компьютеры КАК Компьютеры 
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.Оборудование КАК Оборудование 
ПО Оборудование.Модель = Компьютеры.Модель;

ВЫБРАТЬ РАЗЛИЧНЫЕ Оборудование.Производитель 
ПОМЕСТИТЬ ВТНоутбуки 
ИЗ Справочник.Ноутбуки КАК Ноутбуки 
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.Оборудование КАК Оборудование 
ПО Оборудование.Модель = Ноутбуки.Модель;

ВЫБРАТЬ Компьютеры.Производитель 
ИЗ ВТКомпьютеры КАК Компьютеры 
ЛЕВОЕ СОЕДИНЕНИЕ ВТНоутбуки КАК Ноутбуки 
ПО Компьютеры.Производитель = Ноутбуки.Производитель 
ГДЕ Ноутбуки.Производитель ЕСТЬ NULL;

Почему это работает? При ЛЕВОЕ СОЕДИНЕНИЕ, если Производитель из таблицы ВТКомпьютеры не найден в ВТНоутбуки, система вернет NULL в колонке Производитель из таблицы Ноутбуки. Условие ГДЕ Ноутбуки.Производитель ЕСТЬ NULL отсекает всех тех, кто выпускает и компьютеры, и ноутбуки, оставляя только нужную нам выборку.

Решение задачи с количественными показателями

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

Рассмотрим сценарий работы с таблицами Заказано и Отгружено:

  1. Соединяем таблицы по полю Номенклатура.
  2. Используем функцию ЕСТЬNULL, чтобы корректно обработать отсутствие записей в таблице отгрузки.
  3. Вычисляем разницу между заказанным и отгруженным количеством.

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


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

Почему использование временных таблиц предпочтительнее?

Разберем, почему данный подход считается стандартом индустрии:

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

← На главную