Группировка данных в запросе (СГРУППИРОВАТЬ ПО [ГРУППИРУЮЩИМ НАБОРАМ], ИТОГИ ПО [ОБЩИЕ])

23.04.20

Разработка - Запросы

Для группировки данных в языке запросов 1С существуют конструкции СГРУППИРОВАТЬ ПО [ГРУППИРУЮЩИМ НАБОРАМ], ИТОГИ ПО [ОБЩИЕ]. Для новичков назначение этих конструкций не всегда очевидно, попробуем разобраться на примерах, для чего предназначена каждая из них и в чем отличие от аналогичных конструкций в языке SQL.

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

Контрагент

Товар

Проект

Страна

Количество

Сумма

 

 

КОНСТРУКЦИЯ 1: СГРУППИРОВАТЬ ПО (GROUP BY)

Аналог в языке SQL – GROUP BY, именно в эту конструкцию и транслируется СГРУППИРОВАТЬ ПО.

Секция позволяет получить итоги по комбинации выбранных реквизитов без промежуточных итогов (говоря языком методов таблицы значений, свернуть):

ПРИМЕР 1

ЗАПРОС:

ВЫБРАТЬ

 К

Т

П

 С

 

АГРЕГАТНЫЕ ФУНКЦИИ

 к

 с

                 

СГРУППИРОВАТЬ ПО

 К

 Т

 П

 С

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

РЕЗУЛЬТАТ:

  К

  Т

  П

  С

  к

  с

 

 

Если нужно получить итоги по разным комбинациям группируемых реквизитов в одном запросе, то понадобится конструкция ОБЪЕДИНИТЬ [ВСЕ] (UNION [ALL]) (аналог в языке SQL – UNION [ALL]):

ПРИМЕР 2

ЗАПРОС :

ВЫБРАТЬ

 К

NULL

 П

NULL

АГРЕГАТНЫЕ ФУНКЦИИ

  к

  с

СГРУППИРОВАТЬ ПО

 К

 

 П

       

ОБЪЕДИНИТЬ

             

ВЫБРАТЬ

NULL

 Т

NULL

NULL

АГРЕГАТНЫЕ ФУНКЦИИ

  к

  с

СГРУППИРОВАТЬ ПО

 

 Т

         

ОБЪЕДИНИТЬ

             

ВЫБРАТЬ

NULL

 Т

NULL

 С

АГРЕГАТНЫЕ ФУНКЦИИ

  к

  с

СГРУППИРОВАТЬ ПО

 

 Т

 

 С

     
ВЫБРАТЬ
                Продажи.Контрагент,
                NULL,
                Продажи.Проект,
                NULL,
                СУММА(Продажи.Сумма) КАК Сумма,
                СУММА(Продажи.Количество) КАК Количество
ИЗ
                РегистрНакопления.Продажи КАК Продажи
СГРУППИРОВАТЬ ПО
                Продажи.Контрагент,
                Продажи.Проект
ОБЪЕДИНИТЬ
ВЫБРАТЬ
                NULL,
                Продажи.Товар,
                NULL,
                NULL,
                СУММА(Продажи.Сумма) КАК Сумма,
                СУММА(Продажи.Количество) КАК Количество
ИЗ
                РегистрНакопления.Продажи КАК Продажи
СГРУППИРОВАТЬ ПО
                Продажи.Товар
ОБЪЕДИНИТЬ
ВЫБРАТЬ
                NULL,
                Продажи.Товар,
                NULL,
                Продажи.Страна,
                СУММА(Продажи.Сумма) КАК Сумма,
                СУММА(Продажи.Количество) КАК Количество
ИЗ
                РегистрНакопления.Продажи КАК Продажи
СГРУППИРОВАТЬ ПО
                Продажи.Товар,
                Продажи.Страна

РЕЗУЛЬТАТ:

  К

 

  П

 

  к

  с

 

  Т

   

  к

  с

 

  Т

 

  С

  к

  с

 

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


КОНСТРУКЦИЯ 2: ИТОГИ ПО [ОБЩИЕ] (TOTALS BY [OVERALL])

Аналог в языке SQL – WITH ROLLUP, но конструкция ИТОГИ ПО не транслируется в SQL-запрос, а обрабатывается самой платформой.

Конструкция позволяет применить к исходной выборке дополнительные группировки и присоединить к выборке полученные итоги. Итоги собираются по автоматически формирующимся комбинациям реквизитов секции ПО по следующему правилу: комбинация из первого реквизита, комбинация из первых двух реквизитов, комбинация из первых трех реквизитов и т.д. до последнего реквизита. Результат вполне себе можно назвать деревом с итогами по узлам, что, в общем-то, закрывает большинство задач по группировке данных одинэсника.

ПРИМЕР 3

ЗАПРОС:

ВЫБРАТЬ

  К

  Т

  П

  С

     
               

ИТОГИ

       

АГРЕГАТНЫЕ ФУНКЦИИ

  к

  с

               

ПО

  К

 

  П

  С

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

РЕЗУЛЬТАТ:

 

  К

     

  к

  с

  К

 

  П

 

  к

  с

  К

 

  П

  С

  к

  с

  К

  Т

  П

  С

  к

  с

  К

  Т

  П

  С

  к

  с

Отобрано по значению «Контрагент 4» для наглядности:

Если используется ключевое слово ОБЩИЕ, то дополнительно добавляется итоговая строка самого верхнего уровня.

Запрос с секцией ИТОГИ ПО может содержать секцию СГРУППИРОВАТЬ ПО (в языке SQL он как раз-таки должен содержать ее), но со своими агрегатными функциями (в отличие от SQL). В этом случае есть ограничение: реквизиты, агрегированные в секции СГРУППИРОВАТЬ ПО, не могут выступать реквизитами группировки в секции ИТОГИ ПО, например, если количество было уже просуммировано агрегатной функцией, итоги по нему как по полю группировки посчитать уже не получится (в языке SQL и для группировки, и для итогов используются одни и те же агрегатные функции.

ПРИМЕР 4

ЗАПРОС:

ВЫБРАТЬ

  К

   Т

  П

  С

АГРЕГАТНЫЕ ФУНКЦИИ

  к

  с

СГРУППИРОВАТЬ ПО

  К

   Т

  П

  С

     

ИТОГИ

       

АГРЕГАТНЫЕ ФУНКЦИИ

  к

 

ПО

  К

 

  П

  С

     
ВЫБРАТЬ
   Продажи.Контрагент КАК Контрагент,
   Продажи.Товар КАК Товар,
   Продажи.Проект КАК Проект,
   Продажи.Страна КАК Страна,
   СУММА(Продажи.Сумма) КАК Сумма,
   СУММА(Продажи.Количество) КАК Количество
ИЗ
   РегистрНакопления.Продажи КАК Продажи
СГРУППИРОВАТЬ ПО
   Продажи.Контрагент,
   Продажи.Товар,
   Продажи.Проект,
   Продажи.Страна
ИТОГИ
   СРЕДНЕЕ(Количество)
ПО
   Контрагент,
   Проект,
   Страна

РЕЗУЛЬТАТ:

  К

     

  к

  с

  К

 

  П

 

  к

  с

  К

 

  П

  С

  к

  с

  К

  Т

  П

  С

  к

  с

 

 

КОНСТРУКЦИЯ 3: СГРУППИРОВАТЬ ПО ГРУППИРУЮЩИМ НАБОРАМ  (GROUP BY GROUPING SETS)

Аналог в языке SQL - GROUP BY GROUPING SETS, именно в эту конструкцию и транслируется СГРУППИРОВАТЬ ПО ГРУППИРУЮЩИМ НАБОРАМ.

Начиная с версии платформы 1С 8.3.16 в языке запросов появилось расширение ГРУППИРУЮЩИМ НАБОРАМ секции СГРУППИРОВАТЬ ПО. В конструкторе запросов это выглядит следующим образом:

Данная конструкция позволяет существенно упростить запрос из примера 2  (за тем исключением, что нет возможности использовать разные агрегатные функции для разных комбинаций реквизитов):

ПРИМЕР 5

ЗАПРОС:

ВЫБРАТЬ

  К

  Т

  П

  С

АГРЕГАТНЫЕ ФУНКЦИИ

  к

  с

               

СГРУППИРОВАТЬ ПО ГРУППИРУЮЩИМ НАБОРАМ

  К

 

  П

       
 

  Т

         
 

  Т

 

  С

     
ВЫБРАТЬ
   Продажи.Контрагент КАК Контрагент,
   Продажи.Товар КАК Товар,
   Продажи.Проект КАК Проект,
   Продажи.Страна КАК Страна,
   СУММА(Продажи.Сумма) КАК Сумма,
   СУММА(Продажи.Количество) КАК Количество
ИЗ
   РегистрНакопления.Продажи КАК Продажи
СГРУППИРОВАТЬ ПО ГРУППИРУЮЩИМ НАБОРАМ
( 
(  Продажи.Контрагент,Продажи.Проект),
(  Продажи.Товар),
(  Продажи.Товар,
   Продажи.Страна)
)

РЕЗУЛЬТАТ:

  К

 

  П

 

  к

  с

 

  Т

   

  к

  с

 

  Т

 

  С

  к

  с

 

 

Отмечу, что если указать единственный набор из всех реквизитов группировки, то результат запроса будет идентичен запросу без расширения ПО ГРУППИРУЮЩИМ НАБОРАМ, т.е. обычная группировка по всем реквизитам, как в запросе из примера 1.

Если область применения предыдущих конструкций вопросов не вызывает, то ценность конструкции СГРУППИРОВАТЬ ПО ГРУППИРУЮЩИМ НАБОРАМ не сразу очевидна рядовому одинэснику. Я не стал копировать пример из Зазеркалья https://wonderland.v8.1c.ru/blog/podderzhka-grouping-sets-v-yazyke-zaprosov/, а решил придумать свой. Хороший пример в данном случае придумать непросто, т.к. большинство наборов данных в типовых конфигурациях можно успешно описать деревом, за счет чего минимальный функционал СКД закрывает большую часть задач. Кроме того, такие типичные отчеты, как дебиторская/кредиторская задолженность, продажи, как правило, содержат связанные или даже подчиненные друг другу аналитики, например, договор подчинен контрагенту, документ содержит ссылку на договор и т.д., вследствие чего получение итогов по нескольким отдельным аналитикам требуется крайне редко. Но есть сфера, в которой подобные разреженные матрицы используются повсеместно – это OLAP. Потенциально конструкция может принести в этой сфере, если запросы к OLAP-источникам пишутся на языке 1С.

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

Стоит добавить, что в языке SQL у секции GROUP BY есть расширение WITH CUBE, выводящее итоги по всем возможным комбинациям реквизитов группировки. Его аналога в языке запросов 1С нет, но с помощью конструкций, использованных в примерах 2 и 5 можно добиться того же результата, хотят и с бОльшими трудозатратами.

Всем добра!

СГРУППИРОВАТЬ ПО ГРУППИРУЮЩИМ НАБОРАМ ИТОГИ GROUP BY GROUPING SETS TOTALS CUBE ROLLUP

См. также

Infostart Toolkit: Инструменты разработчика 1С 8.3 на управляемых формах

Инструментарий разработчика Роли и права Запросы СКД Платформа 1С v8.3 Управляемые формы Запросы Система компоновки данных Конфигурации 1cv8 Платные (руб)

Набор инструментов программиста и специалиста 1С для всех конфигураций на управляемых формах. В состав входят инструменты: Консоль запросов, Консоль СКД, Консоль кода, Редактор объекта, Анализ прав доступа, Метаданные, Поиск ссылок, Сравнение объектов, Все функции, Подписки на события и др. Редактор запросов и кода с раскраской и контекстной подсказкой. Доработанный конструктор запросов тонкого клиента. Продукт хорошо оптимизирован и обладает самым широким функционалом среди всех инструментов, представленных на рынке.

10000 руб.

02.09.2020    124511    681    389    

732

Пропорциональное распределение в запросе с использованием АвтоНомерЗаписи()

Запросы Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Часто поступают задачи по произвольному распределению общих сумм. После распределения иногда пропадают копейки. Суть решения добавить АвтоНомерЗаписи() в ВТ распределения, и далее используя функции МАКСИМУМ или МИНИМУМ можем положить разницу копеек в первую или последнюю строку знаменателя распределения.

11.04.2024    1939    andrey_sag    5    

25

Для чего используют конструкцию запроса "ГДЕ ЛОЖЬ" в СКД на примере конфигурации 1С:ERP

Запросы СКД Платформа 1С v8.3 Запросы Система компоновки данных 1С:ERP Управление предприятием 2 Бесплатно (free)

В типовых конфигурациях разработчики компании 1С иногда используют в отчетах, построенных на СКД, такую конструкцию, как "ГДЕ ЛОЖЬ". Такая конструкция говорит о том, что данные в запросе не будут получены совсем. Для чего же нужен тогда запрос?

13.02.2024    5961    KawaNoNeko    23    

25

Набор-объект для СКД по тексту или запросу

Запросы СКД Платформа 1С v8.3 Управляемые формы Конфигурации 1cv8 Абонемент ($m)

Есть список полей в виде текста, или запрос - закидываем в набор СКД.

1 стартмани

31.01.2024    2127    2    Yashazz    0    

30

Запрос 1С copilot

Инструментарий разработчика Запросы Платформа 1С v8.3 Управляемые формы Конфигурации 1cv8 Абонемент ($m)

Пишем на человеческом языке, что нам надо, и получаем текст запроса на языке 1С. Используются большие языковые модели (LLM GPT) от OpenAI или Яндекс на выбор.

5 стартмани

15.01.2024    6584    31    mkalimulin    27    

51

PrintWizard: поддержка представлений ЗУП в конструкторе

Инструментарий разработчика Запросы Платформа 1С v8.3 Бесплатно (free)

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

14.12.2023    1871    vandalsvq    7    

29

Объектная модель запроса "Схема запроса" 2

Запросы Платформа 1С v8.3 Запросы Конфигурации 1cv8 Бесплатно (free)

Далеко уже не новый тип данных "Схема запроса". Статья о том, как использовать его "попроще". Примеры создания текста запроса с нуля и изменение имеющегося запроса.

06.12.2023    5591    user1923546    26    

46

Начните уже использовать хранилище запросов

HighLoad оптимизация Запросы

Очень немногие из тех, кто занимается поддержкой MS SQL, работают с хранилищем запросов. А ведь хранилище запросов – это очень удобный, мощный и, главное, бесплатный инструмент, позволяющий быстро найти и локализовать проблему производительности и потребления ресурсов запросами. В статье расскажем о том, как использовать хранилище запросов в MS SQL и какие плюсы и минусы у него есть.

11.10.2023    16544    skovpin_sa    14    

101
Комментарии
Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. VmvLer 19.09.19 15:57 Сейчас в теме
запросы понятны, спасибо.
цветные квадратики бесят, возможно это потому, что я не курю.

Применимо к динамическим ABC, например.
Я, чтобы сгруппировать группировки в СКД делал выполнение два раза:
1-й раз получал через СКД ABC набор по определенным показателям.
2-й раз группировал его в классическое ABC-дерево.

похоже, теперь можно делать такие отчеты группировка по группировкам в один проход.
maksa2005; criptid; ivangrant; nikivr; paybaseme; Kontakt; +6 Ответить
2. sertak 314 19.09.19 16:03 Сейчас в теме
(1) Я не знаю как правильно, попробую в следующий раз монохром. Идей много, короче.
3. CSiER 35 21.09.19 06:59 Сейчас в теме
Спасибо за статью, визуализация отличная.
Arzv; t278; Риник; ivangrant; ikalmykia; Novinsky; conductor; hame1e00n; user774630; sertak; +10 Ответить
4. sertak 314 21.09.19 09:40 Сейчас в теме
5. ILM 240 23.09.19 05:26 Сейчас в теме
Квадратики цветные это для младшей ясельной группы. Для средней подготовительной уже нужны карточки с рисунками: домики, грибочки, яблочки и т.д.
uk09; rovenko.n; maksa2005; Nik39; Vova_Di; Риник; kyrasol; ivangrant; Irwin; hame1e00n; +10 Ответить
6. sertak 314 23.09.19 06:20 Сейчас в теме
(5) Отпишитесь, когда перейдете в среднюю, я переделаю статью.
native-api; user2032828; Krio2; NikeeNik; Kazaams; michmich; rovenko.n; cheburashka; t278; maksa2005; andryandry; Nik39; ivangrant; ixijixi; almierm; russb; Krasnyj; user1290312; Novinsky; hame1e00n; IgorS; +21 Ответить
7. ILM 240 23.09.19 16:50 Сейчас в теме
(6) Эх, опоздали! У нас весной выпускной был! Теперь в первом классе)))
8. Diks_Soft 146 27.01.20 09:13 Сейчас в теме
Спасибо! И с цветными квадратиками все норм)
Arzv; t278; sertak; +3 Ответить
9. Ibrogim 1313 28.02.20 11:20 Сейчас в теме
Спасибо, однозначно +, узнал про "СГРУППИРОВАТЬ ПО ГРУППИРУЮЩИМ НАБОРАМ" )
Может я не визуал, но мне вспомнить какой цветной квадрат что означает почти нереально

Прям бы в квадрате мелким шрифтом "Пр-т" Тов." "Кол" и т.п.
10. Cvetic 307 07.07.21 11:22 Сейчас в теме
11. TerveRus 10.08.21 14:15 Сейчас в теме
Вопрос: как во второй картинке с итогами получить корректные средние итоги по проекту/контрагенту по предыдущей группировке (по стране), а не по детальным записям?
Столкнулся с тем, что итоги считаются только по детальным записям, а не по каждому предыдущему уровню отдельно.

Запрос считает:
Беларусь - 3
Россия - 4
Казахстан - 1
Казахстан - 1
Среднее по проекту: (3+4+1+1) / 4 = 2.25

А должно быть:
Беларусь - 3
Россия - 4
Казахстан - 1
Среднее по проекту: (3+4+1) / 3 = 2.67
12. t278 56 08.12.21 09:24 Сейчас в теме
Цветные квадратики!!!!!
1) понятны!
2) наглядны!
Супер решение!
13. sertak 314 08.12.21 13:03 Сейчас в теме
(12) Спасибо, рад, что статья полезна.
14. ВасяЧ 21.01.22 12:49 Сейчас в теме
Эх, ничегошеньки не понятно(

Поле цветных квадратиков хотелось бы пояснение, а что по мнению автора должно было получиться.
15. tarroman 07.04.22 12:23 Сейчас в теме
Пока пример не разобрал в деталях, вот эту фразу не мог осилить (и там и там "реквизиты") :)
"В этом случае есть ограничение: реквизиты, агрегированные в секции СГРУППИРОВАТЬ ПО, не могут выступать реквизитами группировки в секции ИТОГИ ПО, например, если количество было уже просуммировано агрегатной функцией, итоги по нему как по полю группировки посчитать уже не получится (в языке SQL и для группировки, и для итогов используются одни и те же агрегатные функции."

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

Цветные квадратики - это нечто. Но нужно с ними сразу разобраться (понять принципы и запомнить "легенду"), тогда дальше все становится понятным.
16. sertak 314 08.04.22 16:03 Сейчас в теме
(15) Если написать "участвующие в агрегатных функциях", то становится неясно, в каком качестве - в качестве реквизита группировки или если к нему самому была применена агрегатная функция. Вообще, как ни переформулируй, трудно угодить абсолютно всем читателям статьи, при построении фраз ориентировался на себя. Спасибо за отзыв ).
17. tarroman 08.04.22 19:52 Сейчас в теме
(16) Участвующие в агрегатных функциях в качестве аргумента ;)
Оставьте свое сообщение