Заметки из Зазеркалья

04.07.2019

Поддержка GROUPING SETS в языке запросов

Данная статья является анонсом новой функциональности.
Не рекомендуется использовать содержание данной статьи для освоения новой функциональности.
Полное описание новой функциональности будет приведено в документации к соответствующей версии.
Полный список изменений в новой версии приводится в файле v8Update.htm.

Реализовано в версии 8.3.16.1030

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

Допустим, при запуске приложения нужно вывести быстро две диаграммы по одним данным с разной группировкой (например, отдельно по организации и товару, отдельно по организации и клиенту).
Конструкция СГРУППИРОВАТЬ ПО позволяет более эффективно (быстрее) получить несколько группировок за счет использования специальных возможностей СУБД:
  • Oracle – начиная с версии 10.2 (кроме строковых полей)
  • PostgreSQL –  начиная с версии 10.3
  • IBM DB2 – начиная с версии 11
  • MSSQL – начиная с версии 2008

Пример: у нас есть регистр сведений ШтатноеРасписание:

img-01.png

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

Раньше это можно было сделать только так – сделав три запроса и объединив их результаты:

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

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

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

Теперь этот запрос можно написать гораздо изящнее:

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

( РегистрСведенийШтатноеРасписание.Отдел,
 РегистрСведенийШтатноеРасписание.Должность,
 РегистрСведенийШтатноеРасписание.Руководитель),
( РегистрСведенийШтатноеРасписание.Отдел,
 РегистрСведенийШтатноеРасписание.Должность),
( РегистрСведенийШтатноеРасписание.Должность,
 РегистрСведенийШтатноеРасписание.Руководитель)
)

Содержимое регистра:

img-02.png
Результат запроса:

img-03.png

Поддержка конструкции GROUPING SETS позволит в ряде случаев в разы сократить количество строк в запросах и сделать их более читаемыми.


Теги: разработка  8.3.16