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