Перейти к основному содержимому
Версия: 6.x

Оператор GROUP

Оператор GROUP - создание свойства, реализующего группировку.

Синтаксис

GROUP 
type [expr1, ..., exprN]
[orderClause]
[TOP topExpr [OFFSET offsetExpr]]
[WHERE whereExpr]
[BY groupExpr1, ..., groupExprM]

Подправило type, которое используется сразу после GROUP, имеет следующий синтаксис:

SUM | MAX | MIN | AGGR | NAGGR | EQUAL | CONCAT | LAST | CUSTOM [NULL] [className] aggrFunc

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

[WITHIN] ORDER [DESC] orderExpr1, ..., orderExprK

Здесь type задает вид агрегирующей функции, а orderClause задает форму упорядочивания: обычный ORDER ... либо WITHIN ORDER ... для ordered-set CUSTOM-агрегатов.

Описание

Оператор GROUP создает свойство, реализующее группировку. Тип группировки определяется видом агрегирующей функции. Этот оператор отличается от других тем, что может неявно объявлять свои параметры в используемых выражениях (по аналогии с инструкцией =, когда параметры не заданы явно). При этом, важно понимать, что эти "неявно объявленные" параметры не являются параметрами создаваемого свойства (которые на самом деле определяются блоком BY и/или использованными верхними параметрами)

Блок BY описывает группировочные выражения. Каждое выражение соответствует параметру, создаваемого свойства. Как и в остальных операторах, в этом операторе разрешено использовать верхние параметры, причем использованные параметры также неявно являются группировками создаваемого свойства. Если блок BY не задан и верхние параметры не используются, все подходящие наборы объектов образуют одну группу, а создаваемое свойство не имеет параметров. Соответственно, при использовании оператора в инструкции = и явном задании в этой инструкции параметров слева, выражения из блока BY отображаются только на неиспользованные параметры. При этом, если классы или количество этих параметров будет не соответствовать количеству / классам выражений BY, платформа выдаст ошибку.

к сведению

Если блок BY задан, этот оператор нельзя использовать внутри выражений.

Блок ORDER определяет порядок, в котором будет вычисляться агрегирующая функция. Для CONCAT и LAST он обязателен. Для коммутативных агрегаторов (SUM, MAX, MIN, EQUAL, AGGR, NAGGR) он может быть задан дополнительно; в этом случае порядок не меняет итоговое значение сам по себе, но влияет на то, какие записи попадут в агрегирование при использовании TOP / OFFSET. Если функция некоммутативна, порядок следует задавать так, чтобы он был однозначно определяемым. Если в выражениях, задающих порядок, объявляется новый параметр (не использующийся в остальных блоках и в верхнем контексте), то при вычислении результирующего значения автоматически добавляется условие на не NULL всех этих выражений.

Для CUSTOM-агрегатов ключевое слово WITHIN не задает какой-то отдельный "дополнительный порядок", а выбирает форму SQL-вызова пользовательской / встроенной агрегатной функции. Без WITHIN порядок передается внутрь самого вызова функции, то есть конструкция вида GROUP CUSTOM ... 'aggrFunc' expr1, ..., exprN ORDER orderExpr1, ... соответствует вызову aggrFunc(expr1, ..., exprN ORDER BY orderExpr1, ...). С WITHIN используется ordered-set форма, то есть GROUP CUSTOM ... 'aggrFunc' expr1, ..., exprN WITHIN ORDER orderExpr1, ... соответствует вызову aggrFunc(expr1, ..., exprN) WITHIN GROUP (ORDER BY orderExpr1, ...). Это важно для агрегатов, которые в СУБД определены именно через WITHIN GROUP, например percentile_cont.

С точки зрения результата различие в том, какие именно значения считаются "входом" агрегата. Без WITHIN агрегат вычисляет результат по значениям expr1, ..., exprN, а ORDER только задает порядок их обработки. С WITHIN результат вычисляется по упорядоченному набору значений из ORDER: именно они образуют выборку, по которой считается агрегат, а expr1, ..., exprN становятся параметрами самой агрегатной функции. Например, в GROUP CUSTOM ... 'percentile_cont' 0.9 WITHIN ORDER value(i) выражение 0.9 задает, какой процентиль нужен, а результатом будет 90-й процентиль значений value(i) внутри группы.

Блок TOP и его опциональное продолжение OFFSET ограничивают множество записей, уже отобранных для агрегирования внутри каждой группы: сначала применяется смещение OFFSET, затем берутся следующие TOP записей в заданном порядке. Блок OFFSET отдельно без TOP не используется. Если блок ORDER не задан, выбор этих записей происходит в произвольном порядке.

Блок WHERE определяет условие, при выполнении которого наборы объектов будут участвовать в операции группировки. Его можно задавать только для агрегирующих функций AGGR, NAGGR, CONCAT, LAST. Для LAST, если WHERE не задан, в качестве условия используется не NULL-ность самого агрегируемого выражения.

к сведению

Для AGGR, NAGGR использовать этот блок явно (а не, скажем, оператор IF в блоках GROUP и BY) имеет смысл, только с точки зрения возможности изменения создаваемого свойства на не NULL в некоторых автоматических механизмах платформы (например, в автоматическом разрешении простых ограничений).

Параметры

  • type

    Тип агрегирующей функции. Может иметь одно из следующих встроенных значений: SUM, MAX, MIN, CONCAT, EQUAL, AGGR, NAGGR, LAST, либо форму CUSTOM [NULL] [className] aggrFunc.

  • NULL

    Ключевое слово. Используется только для CUSTOM-агрегатов и указывает, что агрегат может возвращать NULL, даже если все значения параметров не равны NULL.

  • className

    Имя встроенного класса возвращаемого значения. Используется только для CUSTOM-агрегатов и позволяет явно задать тип результата. Если не задан, тип результата выводится из основного выражения агрегата: обычно из первого основного операнда, а для формы с WITHIN и для формы без основных операндов - из первого выражения в ORDER.

  • aggrFunc

    Строковый литерал с именем пользовательской или встроенной в СУБД агрегатной функции. Используется только для CUSTOM-агрегатов.

  • expr1, ..., exprN

    Список выражений, значения которых идут на вход агрегирующей функции в качестве операндов. Количество выражений должно соответствовать количеству операндов используемой функции. Для SUM, MAX, MIN, EQUAL, AGGR, NAGGR поддерживается одно выражение. Для SUM это выражение должно иметь числовой класс семейства IntegralClass (например, INTEGER, LONG, NUMERIC, DOUBLE). Для AGGR и NAGGR операндом должен быть простой объектный параметр, а не произвольное выражение. Для CONCAT поддерживаются либо два выражения: агрегируемое значение и разделитель, либо одно выражение JSON / JSONTEXT-типа. Для LAST указывается одно выражение, а условие отбора задается через WHERE либо выводится автоматически из не NULL-ности этого выражения. Для CUSTOM-агрегатов список может быть пустым, но тогда блок ORDER / WITHIN ORDER обязателен.

  • groupExpr1, ..., groupExprM

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

  • WITHIN

    Ключевое слово. Используется только для CUSTOM-агрегатов и задает ordered-set форму вызова агрегатной функции. Без WITHIN выражения из ORDER передаются внутрь вызова агрегата: aggrFunc(... ORDER BY ...). С WITHIN они выносятся в отдельную часть SQL-вызова: aggrFunc(...) WITHIN GROUP (ORDER BY ...). С функциональной точки зрения это означает, что без WITHIN агрегат работает по значениям основных выражений, а с WITHIN - по упорядоченным значениям из ORDER, тогда как основные выражения становятся параметрами самой функции. Для остальных типов не применяется.

  • DESC

    Ключевое слово. Указывает на обратный порядок просмотра наборов объектов.

  • orderExpr1, ..., orderExprK

    Список выражений, определяющих порядок, в котором будут просматриваться наборы объектов при вычислении агрегирующей функции. Для определения порядка сначала используется значение первого выражения, затем при равенстве используется значение второго и т.д. Для CONCAT и LAST этот список обязателен. Для CUSTOM-агрегатов он обязателен, если список основных выражений не задан.

  • TOP topExpr

    В агрегировании внутри каждой группы будут участвовать только первые n записей, где n - значение выражения topExpr.

  • OFFSET offsetExpr

    Опциональное продолжение блока TOP. В агрегировании внутри каждой группы будут участвовать только записи, начиная со смещения m, где m - значение выражения offsetExpr.

  • whereExpr

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

Примеры

CLASS Game;
CLASS Team;
hostGoals = DATA INTEGER (Game);
hostTeam = DATA Team (Game);
date = DATA DATE (Game);
hostGoalsScored(team) = GROUP SUM hostGoals(Game game) BY hostTeam(game);
last3HostGoalsScored(team) = GROUP SUM hostGoals(Game game) ORDER DESC date(game), game TOP 3 BY hostTeam(game);

name = DATA STRING[100] (Country);
// получается свойство (STRING[100]) -> Country
countryName = GROUP AGGR Country country BY name(country);

CLASS Book;
CLASS Tag;
name = DATA STRING[100] (Tag);
in = DATA BOOLEAN (Book, Tag);

tags(Book b) = GROUP CONCAT name(Tag t) IF in(b, t), ', ' ORDER name(t), t TOP 10 OFFSET 0;

value = DATA NUMERIC[14,2] (INTEGER);
// 90-й процентиль значений value(i)
percentile90() = GROUP CUSTOM NUMERIC[14,2] 'percentile_cont' 0.9 WITHIN ORDER value(INTEGER i);