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