Когда стоит использовать объединение запросов в 1С?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Объединение запросов (UNION) в 1С: когда и зачем
Объединение запросов (UNION) — это операция, которая комбинирует результаты нескольких SELECT запросов в один набор результатов. Это мощный инструмент для специфических случаев работы с данными.
Что такое UNION?
UNION — это оператор SQL, который объединяет результаты двух или более запросов:
Запрос = Новый Запрос(
"ВЫБРАТЬ
| Ссылка,
| Номер,
| Дата,
| Счёт Как ТипДокумента
|ИЗ
| Документ.СчётФактура
|
|ОБЪЕДИНИТЬ
|
|ВЫБРАТЬ
| Ссылка,
| Номер,
| Дата,
| Накладная Как ТипДокумента
|ИЗ
| Документ.Накладная
"
);
Результат = Запрос.Выполнить();
Этот запрос вернёт ВСЕ счета И ВСЕ накладные в одном наборе.
Две разновидности UNION
1. UNION (исключает дубликаты)
// UNION автоматически удаляет дубликаты
Запрос = Новый Запрос(
"ВЫБРАТЬ
| Товар
|ИЗ
| ТаблицаЗначений
|
|ОБЪЕДИНИТЬ
|
|ВЫБРАТЬ
| Товар
|ИЗ
| ДругаяТаблица"
);
// Если в обеих таблицах есть одинаковый Товар,
// он выведется только один раз
2. UNION ALL (включает дубликаты)
// UNION ALL сохраняет все строки, даже дубликаты
Запрос = Новый Запрос(
"ВЫБРАТЬ
| Товар
|ИЗ
| ТаблицаЗначений
|
|ОБЪЕДИНИТЬ ВСЕ
|
|ВЫБРАТЬ
| Товар
|ИЗ
| ДругаяТаблица"
);
// Дубликаты будут выведены столько раз, сколько они встречаются
Когда использовать UNION?
1. Объединение однотипных документов
История всех движений товара из разных документов:
Запрос = Новый Запрос(
"ВЫБРАТЬ
| ПриходОрдер.Дата,
| ПриходОрдер.Номер,
| ПриходОрдер.Товар,
| ПриходОрдер.Количество,
| Приход Как ТипДокумента
|ИЗ
| Документ.ПриходОрдер Как ПриходОрдер
|ГДЕ
| ПриходОрдер.Дата >= &ДатаНачала
|
|ОБЪЕДИНИТЬ ВСЕ
|
|ВЫБРАТЬ
| РасходОрдер.Дата,
| РасходОрдер.Номер,
| РасходОрдер.Товар,
| -РасходОрдер.Количество, -- Минус для расхода
| Расход Как ТипДокумента
|ИЗ
| Документ.РасходОрдер Как РасходОрдер
|ГДЕ
| РасходОрдер.Дата >= &ДатаНачала
|
|ПОРЯДОК ПО
| Дата, ТипДокумента"
);
Запрос.УстановитьПараметр("ДатаНачала", 20240101);
Результат = Запрос.Выполнить();
2. Получение всех контактов из разных источников
Объединение контактов сотрудников и контрагентов:
Запрос = Новый Запрос(
"ВЫБРАТЬ
| Сотрудники.ФИО,
| Сотрудники.Телефон,
| Сотрудник Как ТипКонтакта
|ИЗ
| Справочник.Сотрудники Как Сотрудники
|ГДЕ
| НЕ Сотрудники.ПометкаУдаления
|
|ОБЪЕДИНИТЬ
|
|ВЫБРАТЬ
| Контрагенты.Наименование,
| Контрагенты.Телефон,
| Контрагент Как ТипКонтакта
|ИЗ
| Справочник.Контрагенты Как Контрагенты
|ГДЕ
| НЕ Контрагенты.ПометкаУдаления
|
|ПОРЯДОК ПО
| 1 -- Сортировка по ФИО/Наименованию"
);
3. Статистика из разных регистров
Объединение данных из остатков и оборотов:
Запрос = Новый Запрос(
"ВЫБРАТЬ
| ОстаткиТоваров.Товар,
| ОстаткиТоваров.Количество,
| Остаток Как ТипДанных
|ИЗ
| РегистрНакопления.ОстаткиТоваров.Остатки(&Дата, ) Как ОстаткиТоваров
|
|ОБЪЕДИНИТЬ
|
|ВЫБРАТЬ
| ОборотыТоваров.Товар,
| ОборотыТоваров.ОборотПриход,
| Приход Как ТипДанных
|ИЗ
| РегистрНакопления.ОстаткиТоваров.Обороты(&ДатаНачала, &ДатаОкончания) Как ОборотыТоваров"
);
Запрос.УстановитьПараметр("Дата", ТекущаяДата());
Запрос.УстановитьПараметр("ДатаНачала", НачалоМесяца(ТекущаяДата()));
Запрос.УстановитьПараметр("ДатаОкончания", КонецМесяца(ТекущаяДата()));
Ограничения и требования UNION
Важные правила:
// ✅ ПРАВИЛЬНО: одинаковое количество колонок и совместимые типы
ВЫБРАТЬ
Номер, -- Строка
Дата, -- Дата
Сумма -- Число
ИЗ Документ.СчётФактура
ОБЪЕДИНИТЬ
ВЫБРАТЬ
Номер, -- Строка
Дата, -- Дата
Сумма -- Число (совместимый тип)
ИЗ Документ.Накладная
// ❌ НЕПРАВИЛЬНО: разное количество колонок
ВЫБРАТЬ
Номер,
Дата
ИЗ Документ.СчётФактура
ОБЪЕДИНИТЬ
ВЫБРАТЬ
Номер,
Дата,
Сумма -- ОШИБКА! Разное количество колонок
ИЗ Документ.Накладная
// ❌ НЕПРАВИЛЬНО: несовместимые типы
ВЫБРАТЬ
Номер, -- Строка
Дата -- Дата
ИЗ Документ.СчётФактура
ОБЪЕДИНИТЬ
ВЫБРАТЬ
Номер, -- Строка (OK)
Контрагент -- Ссылка (НЕСОВМЕСТИМО с Датой!)
ИЗ Документ.Накладная
Практический пример: Реестр всех операций
Процедура ПолучитьРеестрОперацийПоДате(ДатаНачала, ДатаОкончания)
Запрос = Новый Запрос(
"ВЫБРАТЬ
| Счета.Дата,
| Счета.Номер,
| Счёт Как ТипОперации,
| Счета.Контрагент.Наименование Как Контрагент,
| Счета.Сумма,
| Счета.Ссылка
|ИЗ
| Документ.СчётФактура Как Счета
|ГДЕ
| Счета.Дата >= &ДатаНачала
| И Счета.Дата <= &ДатаОкончания
|
|ОБЪЕДИНИТЬ ВСЕ
|
|ВЫБРАТЬ
| Накладные.Дата,
| Накладные.Номер,
| Накладная Как ТипОперации,
| Накладные.Контрагент.Наименование,
| Накладные.Сумма,
| Накладные.Ссылка
|ИЗ
| Документ.Накладная Как Накладные
|ГДЕ
| Накладные.Дата >= &ДатаНачала
| И Накладные.Дата <= &ДатаОкончания
|
|ОБЪЕДИНИТЬ ВСЕ
|
|ВЫБРАТЬ
| Платежи.Дата,
| Платежи.Номер,
| Платёж Как ТипОперации,
| Платежи.Контрагент.Наименование,
| Платежи.Сумма,
| Платежи.Ссылка
|ИЗ
| Документ.ПлатёжПоДорого Как Платежи
|ГДЕ
| Платежи.Дата >= &ДатаНачала
| И Платежи.Дата <= &ДатаОкончания
|
|ПОРЯДОК ПО
| Дата УБЫВ,
| ТипОперации"
);
Запрос.УстановитьПараметр("ДатаНачала", ДатаНачала);
Запрос.УстановитьПараметр("ДатаОкончания", ДатаОкончания);
Результат = Запрос.Выполнить().Выбрать();
Пока Результат.Следующий() Цикл
Сообщение(
Результат.Дата + " | " +
Результат.ТипОперации + " № " + Результат.Номер + " | " +
Результат.Контрагент + " | " +
Результат.Сумма
);
КонецЦикла;
КонецПроцедуры
UNION vs LEFT JOIN: различия
| Аспект | UNION | LEFT JOIN |
|---|---|---|
| Назначение | Комбинирует результаты нескольких запросов | Объединяет две таблицы по условию |
| Результат | Вертикальное объединение (строки добавляются) | Горизонтальное объединение (колонки добавляются) |
| Структура | Одинаковое количество колонок | Может быть разное |
| Производительность | Хороша для небольших выборок | Лучше для больших объёмов |
| Типичный случай | История из разных источников | Связь одной таблицы с другой |
Производительность UNION
Рекомендации:
- Используй UNION ALL вместо UNION — если дубликаты неважны (UNION ALL быстрее)
- Ограничивай результаты — добавляй WHERE для сужения выборки
- Индексируй колонки — на которых есть условия WHERE
- Избегай сложных трансформаций — в UNION запросах
// ✅ ХОРОШО: простой UNION ALL с фильтрацией
ВЫБРАТЬ
Дата, Номер, Сумма
ИЗ Документ.СчётФактура
ГДЕ Дата >= &ДатаНачала
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
Дата, Номер, Сумма
ИЗ Документ.Накладная
ГДЕ Дата >= &ДатаНачала
// ❌ ПЛОХО: сложные трансформации в UNION
ВЫБРАТЬ
ДобавитьМесяц(Дата, 1),
ПОДСТРОКА(Номер, 1, 5),
Сумма * (1 + НДС)
ИЗ Документ.СчётФактура
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
...
Когда НЕ использовать UNION
- Если нужно объединить две таблицы на основе ключа — используй JOIN
- Если нужны разные колонки из разных таблиц — используй LEFT JOIN
- Если нужна агрегация — используй GROUP BY
- Если данные очень большого объёма — рассмотри индексы и оптимизацию
Объединение запросов (UNION) — это элегантный способ комбинирования данных из разных источников при условии, что структура результатов совпадает.