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