Секция ОБЪЕДИНИТЬ [ВСЕ](Объединение запросов)

Язык запросов

Синтаксис и применение Секция ОБЪЕДИНИТЬ [ВСЕ](Объединение запросов) в платформе 1С:Предприятие. Описание и примеры кода.

Полное описание, параметры и ограничения

Секция ОБЪЕДИНИТЬ [ВСЕ](Объединение запросов)

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

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

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

Если поля выборки объединяемых запросов имеют разный тип, то поля результата запроса будут иметь составной тип.

Объединение запросов описывается по следующему правилу:

<Объединение запросов>

|

ОБЪЕДИНИТЬ [ВСЕ] <Описание запроса> [<Объединение запросов>]

Объединение запросов начинается с обязательного ключевого слова ОБЪЕДИНИТЬ, после которого следует описание присоединяемого запроса. Далее может присоединяться еще один запрос и т. д.

По умолчанию при объединении запросов полностью одинаковые строки в результате запроса, сформированные разными запросами, заменяются одной. Если требуется, чтобы были оставлены разные строки, необходимо указать ключевое слово ВСЕ.

Пример:

ВЫБРАТЬ
Накладная.Контрагент,
Накладная.Номенклатура,
СУММА (Накладная.Количество) КАК Приход,
СУММА (0) КАК Расход

ИЗ
Документ.ПриходнаяНакладная.Состав КАК Накладная

СГРУППИРОВАТЬ ПО
Контрагент,
Номенклатура

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
Накладная.Контрагент,
Накладная.Номенклатура,
СУММА (0),
СУММА (Накладная.Количество)

ИЗ
Документ.РасходнаяНакладная.Состав КАК Накладная

СГРУППИРОВАТЬ ПО
Контрагент,
Номенклатура

УПОРЯДОЧИТЬ ПО
Контрагент,
Номенклатура

ИТОГИ ПО
Контрагент

ИТОГИ ОБЩИЕ

Результат запроса:

Контрагент

Номенклатура

Приход

Расход

1 943

151

Трикотажная фабрика "Заря"

443

4

Трикотажная фабрика "Заря"

Брюки детские

3

Трикотажная фабрика "Заря"

Брюки детские

100

Трикотажная фабрика "Заря"

Рубашка "Ковбойка"

200

Трикотажная фабрика "Заря"

Джинсы женские

1

Трикотажная фабрика "Заря"

Джинсы женские

80

Трикотажная фабрика "Заря"

Свитер детский

60

Трикотажная фабрика "Заря"

Кухонный комбайн Крупс

3

Ярмарка одежды

42

Ярмарка одежды

Рубашка "Ковбойка"

20

Ярмарка одежды

Джинсы женские

20

Ярмарка одежды

Мойдодыр "Аквариум"

2

Торговый дом "Буденовский"

53

Торговый дом "Буденовский"

Брюки детские

10

Торговый дом "Буденовский"

Рубашка "Ковбойка"

5

Торговый дом "Буденовский"

Джинсы женские

12

Торговый дом "Буденовский"

Свитер детский

1

Торговый дом "Буденовский"

Раковина "Лилия"

8

Торговый дом "Буденовский"

Мойдодыр "Аквариум"

5

Торговый дом "Буденовский"

Смеситель "Ультра"

10

Торговый дом "Буденовский"

Кухонный комбайн Крупс

2

Павильон 45 на оптовом рынке

44

Павильон 45 на оптовом рынке

Рубашка "Ковбойка"

5

Павильон 45 на оптовом рынке

Джинсы женские

9

Павильон 45 на оптовом рынке

Раковина "Лилия"

10

Павильон 45 на оптовом рынке

Мойдодыр "Аквариум"

20

Бавария – фарфор

1 500

8

Бавария – фарфор

Брюки детские

7

Бавария – фарфор

Джинсы женские

1

Бавария – фарфор

Раковина "Лилия"

270

Бавария – фарфор

Мойдодыр "Аквариум"

230

Бавария – фарфор

Смеситель "Ультра"

1 000

Практические примеры

Различить уникальные коды, уникальные строки и сохранение дублей при объединении

Один код 1 имеет две разные подписи, а пара 1/Книга повторяется трижды в двух списках. РАЗЛИЧНЫЕ сравнивает все выбранные поля; ОБЪЕДИНИТЬ ВСЕ сохраняет каждую исходную строку.

Где и как запускать

Полный серверный общий модуль учебной базы 8.5.1.1343. Собственные списки и приватные временные таблицы, без рабочих источников, внешних файлов и сети; здесь не запускался.

Подготовка

  1. В отдельной учебной базе 8.5.1.1343 создайте общий модуль УчебныйЯзык: Сервер=Истина, Глобальный=Ложь, ВызовСервера=Ложь, Привилегированный=Ложь. Клиентские и внешнее соединение отключены; ПовторноеИспользованиеВозвращаемыхЗначений=НеИспользовать.

  2. Вставьте весь приведённый текст в этот общий модуль. ВыполнитьПример — экспортная точка входа; остальные процедуры и функции располагаются рядом, а не внутри неё.

  3. В своей внешней учебной обработке создайте управляемую форму, команду Выполнить и кнопку. Клиентский обработчик Выполнить(Команда) вызывает свою процедуру ВыполнитьНаСервере(); она имеет директиву &НаСервереБезКонтекста и одну строку УчебныйЯзык.ВыполнитьПример();. Это серверный вызов общего модуля, а не разрешение клиенту прямо обращаться к серверной библиотеке.

  4. Все товары, количества и строки придуманы в этом модуле. Запись документов, подключение к чужой базе, файлы, сеть и печать не используются. В рабочие общие модули текст не вставляйте.

  5. HTML только показывает BSL. Код в 1С не запускался; перечисленные результаты и отрицательные опыты проверяйте самостоятельно в собственном стенде.

  6. Весь исходный состав задан в модуле. Нужна только серверная учебная обработка по общей подготовке; метаданные документов и справочников не требуются.

  7. Вспомогательные СоздатьСвоюТаблицу и ПроверитьСвойСостав входят в полный модуль, а не скрыты в неизвестной библиотеке.

  8. Каждый исходный код целый положительный, каждая подпись строка до 40 символов. Это не данные и не ключи из рабочих систем.

Процедура ВыполнитьПример() Экспорт
    Первый = СоздатьСвоюТаблицу();
    Второй = СоздатьСвоюТаблицу();
    НоваяСтрока = Первый.Добавить();
    НоваяСтрока.Код = 1;
    НоваяСтрока.Название = "Книга";
    НоваяСтрока = Первый.Добавить();
    НоваяСтрока.Код = 1;
    НоваяСтрока.Название = "Книга";
    НоваяСтрока = Первый.Добавить();
    НоваяСтрока.Код = 1;
    НоваяСтрока.Название = "Книга другая";
    НоваяСтрока = Первый.Добавить();
    НоваяСтрока.Код = 2;
    НоваяСтрока.Название = "Ручка";
    НоваяСтрока = Второй.Добавить();
    НоваяСтрока.Код = 1;
    НоваяСтрока.Название = "Книга";
    НоваяСтрока = Второй.Добавить();
    НоваяСтрока.Код = 3;
    НоваяСтрока.Название = "Блокнот";
    Если Первый.Количество() <> 4 Или Второй.Количество() <> 2 Тогда
        ВызватьИсключение "Изменились собственные исходные списки";
    КонецЕсли;
    Менеджер = Новый МенеджерВременныхТаблиц;
    Попытка
        Создание = Новый Запрос;
        Создание.МенеджерВременныхТаблиц = Менеджер;
        Создание.Текст = "ВЫБРАТЬ Первый.Код КАК Код, Первый.Название КАК Название
        |ПОМЕСТИТЬ ВТСвойПервыйСписок
        |ИЗ &Первый КАК Первый;
        |
        |ВЫБРАТЬ Второй.Код КАК Код, Второй.Название КАК Название
        |ПОМЕСТИТЬ ВТСвойВторойСписок
        |ИЗ &Второй КАК Второй";
        Создание.УстановитьПараметр("Первый", Первый);
        Создание.УстановитьПараметр("Второй", Второй);
        Создание.ВыполнитьПакет();
        Запрос = Новый Запрос;
        Запрос.МенеджерВременныхТаблиц = Менеджер;
        Запрос.Текст = "ВЫБРАТЬ РАЗЛИЧНЫЕ Первый.Код КАК КодОбразца
        |ИЗ ВТСвойПервыйСписок КАК Первый
        |УПОРЯДОЧИТЬ ПО КодОбразца";
        Коды = Запрос.Выполнить().Выгрузить();
        Если Коды.Количество() <> 2 Тогда
            ВызватьИсключение "Ожидались два собственных уникальных кода";
        КонецЕсли;
        Сообщить(Коды[0].КодОбразца = 1 И Коды[1].КодОбразца = 2);
        Запрос.Текст = "ВЫБРАТЬ РАЗЛИЧНЫЕ Первый.Код КАК КодОбразца, Первый.Название КАК НаименованиеОбразца
        |ИЗ ВТСвойПервыйСписок КАК Первый
        |УПОРЯДОЧИТЬ ПО КодОбразца, НаименованиеОбразца";
        ПолныеСтроки = Запрос.Выполнить().Выгрузить();
        ПроверитьСвойСостав(ПолныеСтроки, 3, 1, 1, 1, 0);
        Запрос.Текст = "ВЫБРАТЬ Первый.Код КАК КодОбразца, Первый.Название КАК НаименованиеОбразца
        |ИЗ ВТСвойПервыйСписок КАК Первый
        |ОБЪЕДИНИТЬ
        |ВЫБРАТЬ Второй.Код КАК ДругойКод, Второй.Название КАК ДругаяПодпись
        |ИЗ ВТСвойВторойСписок КАК Второй
        |УПОРЯДОЧИТЬ ПО КодОбразца, НаименованиеОбразца";
        Объединение = Запрос.Выполнить().Выгрузить();
        Сообщить("ОБЪЕДИНИТЬ");
        ПроверитьСвойСостав(Объединение, 4, 1, 1, 1, 1);
        Сообщить(Объединение.Колонки.Найти("КодОбразца") <> Неопределено);
        Сообщить(Объединение.Колонки.Найти("ДругойКод") = Неопределено);
        Запрос.Текст = "ВЫБРАТЬ Первый.Код КАК КодОбразца, Первый.Название КАК НаименованиеОбразца
        |ИЗ ВТСвойПервыйСписок КАК Первый
        |ОБЪЕДИНИТЬ ВСЕ
        |ВЫБРАТЬ Второй.Код КАК ДругойКод, Второй.Название КАК ДругаяПодпись
        |ИЗ ВТСвойВторойСписок КАК Второй
        |УПОРЯДОЧИТЬ ПО КодОбразца, НаименованиеОбразца";
        Объединение = Запрос.Выполнить().Выгрузить();
        Сообщить("ОБЪЕДИНИТЬ ВСЕ");
        ПроверитьСвойСостав(Объединение, 6, 3, 1, 1, 1);
        Сообщить(Объединение.Колонки.Найти("КодОбразца") <> Неопределено);
        Сообщить(Объединение.Колонки.Найти("ДругойКод") = Неопределено);
        Запрос.Текст = "ВЫБРАТЬ Объединённые.КодОбразца КАК КодОбразца, КОЛИЧЕСТВО(*) КАК Повторений
        |ИЗ (
        |ВЫБРАТЬ Первый.Код КАК КодОбразца, Первый.Название КАК НаименованиеОбразца
        |ИЗ ВТСвойПервыйСписок КАК Первый
        |ОБЪЕДИНИТЬ ВСЕ
        |ВЫБРАТЬ Второй.Код КАК ДругойКод, Второй.Название КАК ДругаяПодпись
        |ИЗ ВТСвойВторойСписок КАК Второй
        |) КАК Объединённые
        |СГРУППИРОВАТЬ ПО Объединённые.КодОбразца
        |УПОРЯДОЧИТЬ ПО КодОбразца";
        Частоты = Запрос.Выполнить().Выгрузить();
        Если Частоты.Количество() <> 3 Тогда
            ВызватьИсключение "Ожидались три собственные группы";
        КонецЕсли;
        Сообщить(Частоты[0].КодОбразца = 1 И Частоты[0].Повторений = 4);
        Сообщить(Частоты[1].КодОбразца = 2 И Частоты[1].Повторений = 1);
        Сообщить(Частоты[2].КодОбразца = 3 И Частоты[2].Повторений = 1);
    Исключение
        Менеджер.Закрыть();
        ВызватьИсключение;
    КонецПопытки;
    Менеджер.Закрыть();
КонецПроцедуры

Функция СоздатьСвоюТаблицу()
    Источник = Новый ТаблицаЗначений;
    Источник.Колонки.Добавить("Код", Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(5, 0, ДопустимыйЗнак.Неотрицательный)));
    Источник.Колонки.Добавить("Название", Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(40)));
    Возврат Источник;
КонецФункции

Процедура ПроверитьСвойСостав(Таблица, ОжидалосьВсего, ОжидалосьКниг, ОжидалосьДругихКниг, ОжидалосьРучек, ОжидалосьБлокнотов)
    Если Таблица.Количество() <> ОжидалосьВсего Тогда
        ВызватьИсключение "Число собственных строк не совпало";
    КонецЕсли;
    Книги = Таблица.НайтиСтроки(Новый Структура("КодОбразца,НаименованиеОбразца", 1, "Книга"));
    ДругиеКниги = Таблица.НайтиСтроки(Новый Структура("КодОбразца,НаименованиеОбразца", 1, "Книга другая"));
    Ручки = Таблица.НайтиСтроки(Новый Структура("КодОбразца,НаименованиеОбразца", 2, "Ручка"));
    Блокноты = Таблица.НайтиСтроки(Новый Структура("КодОбразца,НаименованиеОбразца", 3, "Блокнот"));
    Если Книги.Количество() <> ОжидалосьКниг Или ДругиеКниги.Количество() <> ОжидалосьДругихКниг
        Или Ручки.Количество() <> ОжидалосьРучек Или Блокноты.Количество() <> ОжидалосьБлокнотов Тогда
        ВызватьИсключение "Полный состав собственных строк не совпал";
    КонецЕсли;
    Сообщить("Проверен полный состав строк, всего " + Строка(ОжидалосьВсего));
КонецПроцедуры

Разбор по шагам

  1. Создать свои два типизированных списка: четыре строки слева и две справа. Первая таблица содержит два полных дубля 1/Книга и отдельную строку 1/Книга другая.

  2. Передать оба списка параметрами, создать две приватные временные таблицы собственного менеджера.

  3. РАЗЛИЧНЫЕ только по коду даёт два кода 1 и 2. Добавление подписи меняет идентичность строки: уникальных пар первого списка уже три.

  4. ОБЪЕДИНИТЬ без ВСЕ оставляет четыре разные пары двух списков: одинаковая 1/Книга одна, 1/Книга другая остаётся отдельной.

  5. ОБЪЕДИНИТЬ ВСЕ даёт все шесть строк: пара 1/Книга встречается трижды. Это не ошибка и не исправление данных.

  6. Обе ветви имеют два поля одного смысла в одинаковом порядке. Имена результата берутся из первой ветви; ДругойКод второй ветви не создаёт новую колонку.

  7. Использовать объединение как вложенный источник в скобках и обратиться к его выведенному полю КодОбразца через псевдоним Объединённые.

  8. Сгруппировать шесть строк по коду: частоты 4,1,1. Порядок результатов задаётся явно, а полный состав пар проверяется независимо от сортировки строковых подписей.

  9. Закрыть свой менеджер в обоих исходах; рабочие документы/регистры не читать и не изменять.

Как проверить результат

  1. Уникальных кодов первого списка два, уникальных полных строк три.

  2. Без ВСЕ четыре полные строки; с ВСЕ шесть, из них три одинаковые пары 1/Книга.

  3. Колонка КодОбразца присутствует, колонка ДругойКод отсутствует в обеих объединённых выборках.

  4. Вложенный источник даёт частоты по кодам 4,1,1; сумма частот равна шести.

Ожидаемый результат

Дубли разобраны по полному составу собственных строк, а объединение и вложенный источник показаны в законченном серверном модуле.

На что обратить внимание

  1. РАЗЛИЧНЫЕ не означает уникальность только первого поля: сравнивается вся выбранная строка.

  2. Смена ОБЪЕДИНИТЬ ВСЕ на ОБЪЕДИНИТЬ может потерять значимые повторения. Это не универсальный способ исправить неверный отчёт.

  3. Объединение добавляет строки, соединение связывает источники по условию. В этом уроке нет СОЕДИНЕНИЕ.

  4. Число полей обеих ветвей должно совпадать; поля сопоставляются по позиции, не по псевдониму второй ветви.

  5. Разные типы соответствующих полей дают составной тип. Здесь типы намеренно совпадают, другие типы этим опытом не проверены.

  6. Для РАЗЛИЧНЫЕ выражения сортировки должны входить в список выборки; старую совместимость 8.1 не используйте как обход ограничения.

  7. Проверки Python моделируют только полностью заданные строки, а не запуск запросов в 1С.

Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.

Не хотите разбираться сами?

Адаптируем это решение под вашу базу. Оценка бесплатно.

Оставить задачу

1С, 1С:Предприятие — товарные знаки ООО «1С». Сайт не является официальным представительством фирмы «1С» и не аффилирован с ней.