Как запросом объединить данные по сотруднику из двух таблиц

Программист 1С v8.3 (Управляемые формы) 1С:Зарплата и Управление Персоналом Управленческий учет
← На главную

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

Постановка задачи и базовое решение

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

Рассмотрим по шагам, как это реализовать с помощью операторов объединения. Проанализируем исходные данные. В первой таблице у нас есть поля ПланНач и ПланКон, а во второй — ФактНач и ФактКон. Чтобы они попали в одни и те же колонки результирующей таблицы, нам нужно назначить им одинаковые псевдонимы.


ВЫБРАТЬ
    Отпуска.Сотрудник КАК Сотрудник,
    Отпуска.ПланНач КАК ДатаНачала,
    Отпуска.ПланКон КАК ДатаОкончания
ПОМЕСТИТЬ ВТ_План
ИЗ
    Справочник.Отпуска КАК Отпуска;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    Отпуска.Сотрудник КАК Сотрудник,
    Отпуска.ФактНач КАК ДатаНачала,
    Отпуска.ФактКон КАК ДатаОкончания
ПОМЕСТИТЬ ВТ_Факт
ИЗ
    Справочник.Отпуска КАК Отпуска;

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

Выбор между ОБЪЕДИНИТЬ и ОБЪЕДИНИТЬ ВСЕ

Разберем важный нюанс производительности. Использование оператора ОБЪЕДИНИТЬ (без «ВСЕ») заставляет систему выполнять дополнительную операцию — проверку на уникальность каждой строки. Если в плане и факте встретятся идентичные записи (один и тот же сотрудник, те же даты), система оставит только одну строку. Это требует значительных ресурсов сервера СУБД, так как выполняется неявная группировка по всем полям.

Проанализируем ситуацию: если мы знаем, что плановые и фактические записи — это разные сущности, или нам важно видеть обе строки даже при совпадении дат, следует использовать ОБЪЕДИНИТЬ ВСЕ. Это работает в разы быстрее, так как данные просто добавляются в конец результирующего набора.


ВЫБРАТЬ
    Т.Сотрудник,
    Т.ДатаНачала,
    Т.ДатаОкончания
ИЗ
    ВТ_План КАК Т
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
    Т.Сотрудник,
    Т.ДатаНачала,
    Т.ДатаОкончания
ИЗ
    ВТ_Факт КАК Т

Идентификация источника данных

Часто при выводе на форму пользователю нужно понимать, какая строка относится к плану, а какая — к факту. Если мы просто объединим таблицы, эта информация потеряется. Посмотрим на пример, как можно добавить служебное поле ВидДанных.


ВЫБРАТЬ
    Отпуска.Сотрудник КАК Сотрудник,
    Отпуска.ПланНач КАК ДатаНачала,
    Отпуска.ПланКон КАК ДатаОкончания,
    "План" КАК ВидДанных
ИЗ
    Справочник.Отпуска КАК Отпуска
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
    Отпуска.Сотрудник,
    Отпуска.ФактНач,
    Отпуска.ФактКон,
    "Факт"
ИЗ
    Справочник.Отпуска КАК Отпуска

Такой подход позволяет не только выводить текст в колонку, но и использовать это поле для Условного оформления на форме. Например, можно раскрасить плановые строки курсивом или серым цветом, а фактические — жирным шрифтом.

Группировка и устранение дублей

Рассмотрим подробнее случай, когда данные могут дублироваться и это нежелательно. Если в исходных таблицах много записей, которые могут повторяться, результат объединения стоит поместить в еще одну временную таблицу и выполнить СГРУППИРОВАТЬ ПО. Это позволит схлопнуть идентичные записи по сотруднику и периодам.


ВЫБРАТЬ
    ОбъединенныеДанные.Сотрудник,
    ОбъединенныеДанные.ДатаНачала,
    ОбъединенныеДанные.ДатаОкончания
ИЗ
    (ВЫБРАТЬ
        ВТ_План.Сотрудник,
        ВТ_План.ДатаНачала,
        ВТ_План.ДатаОкончания
    ИЗ
        ВТ_План
    ОБЪЕДИНИТЬ ВСЕ
    ВЫБРАТЬ
        ВТ_Факт.Сотрудник,
        ВТ_Факт.ДатаНачала,
        ВТ_Факт.ДатаОкончания
    ИЗ
        ВТ_Факт) КАК ОбъединенныеДанные
СГРУППИРОВАТЬ ПО
    ОбъединенныеДанные.Сотрудник,
    ОбъединенныеДанные.ДатаНачала,
    ОбъединенныеДанные.ДатаОкончания

Оптимизация: Индексация временных таблиц

Если объем данных велик (тысячи сотрудников и десятки тысяч записей об отпусках), работа с временными таблицами без индексов может замедлить систему. Проанализируем, как ускорить процесс. При создании временных таблиц ВТ_План и ВТ_Факт рекомендуется индексировать поле Сотрудник.

Это особенно важно, если в дальнейшем вы планируете соединять полученный результат с другими таблицами (например, чтобы получить подразделение сотрудника или его должность). Индекс строится в момент помещения данных во временную таблицу: ИНДЕКСИРОВАТЬ ПО Сотрудник.

Обработка пустых значений и NULL

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


ВЫБРАТЬ
    ЕСТЬNULL(Отпуска.Сотрудник, ЗНАЧЕНИЕ(Справочник.Сотрудники.ПустаяСсылка)) КАК Сотрудник,
    ЕСТЬNULL(Отпуска.ПланНач, ДАТАВРЕМЯ(1, 1, 1)) КАК ДатаНачала

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

Использование Системы компоновки данных (СКД)

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

  1. Автоматическая генерация итогов по сотрудникам.
  2. Возможность пользователю самому настраивать группировки (например, по подразделениям).
  3. Корректная работа с периодами через стандартные параметры СКД.

Итоговые рекомендации по оформлению результата

Чтобы данные на форме выглядели логично, в итоговом запросе обязательно используйте секцию УПОРЯДОЧИТЬ ПО. Без нее порядок строк может быть произвольным, что затруднит чтение «таймлайна» отпусков сотрудника.


УПОРЯДОЧИТЬ ПО
    Сотрудник,
    ДатаНачала

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

← На главную