Оператор PARTITION
Оператор PARTITION - создание свойства, реализующего разбиение / упорядочивание либо простое распределение.
Синтаксис
PARTITION
type [expr1, ..., exprN]
[ORDER [DESC] orderExpr1, ..., orderExprK]
[TOP topExpr] [OFFSET offsetExpr]
[BY groupExpr1, ..., groupExprM]
Где type определяется как:
SUM
PREV
LAST
UNGROUP propertyId distributionType
CUSTOM [NULL] [className] aggrFunc
А distributionType определяется как:
PROPORTION [STRICT] ROUND(digits)
LIMIT [STRICT]
Описание
Оператор PARTITION создаёт свойство, которое для каждого набора объектов либо вычисляет агрегирующую функцию по окну разбиения (SUM, PREV, LAST, CUSTOM), либо распределяет некоторое значение среди наборов объектов группы (UNGROUP).
Блок BY описывает группы, на которые будет разбиваться множество наборов объектов. Если блок BY не указывается, то считается, что все наборы объектов входят в одну группу.
Блок ORDER определяет порядок, в котором будет либо вычисляться агрегирующая функция, либо проходить распределение. Если эта функция некоммутативна, заданный порядок должен быть однозначно определяемым. Если в выражениях, задающих порядок, объявляется новый параметр (не встречавшийся ранее в опциях PARTITION и BY и в верхнем контексте), то при вычислении результирующего значения автоматически добавляется условие на не-NULL всех этих выражений.
Блоки TOP и OFFSET ограничивают подмножество записей, отбираемых внутри каждого разбиения: сначала OFFSET пропускает начальные записи, затем берутся следующие TOP записей в заданном порядке. Любой из блоков может быть указан независимо.
Параметры
-
typeТип операции. Может принимать одно из значений:
SUM,PREV,LAST,UNGROUP,CUSTOM. -
propertyIdИдентификатор распределяемого свойства. Значение этого свойства должно быть числового типа, а количество параметров должно совпадать с количеством группировок в блоке
BY. На вход этому свойству передаются объекты, идентифицирующие группу. -
distributionTypeСтратегия распределения. Одна из:
PROPORTION— пропорциональное распределение: значениеpropertyIdделится среди наборов объектов группы пропорционально основному выражению и округляется доdigitsзнаков после запятой.LIMIT— распределение с лимитами: значениеpropertyIdустанавливается для первого набора объектов до лимита, заданного основным выражением; остаток затем устанавливается для следующего набора и так далее.
-
STRICTЗначение
propertyIdдолжно быть расписано точно (без остатка) по наборам объектов группы. Если в результате распределения остаётся остаток (дляPROPORTIONон может быть и отрицательным), он добавляется первому набору объектов в порядкеORDERдляPROPORTIONи последнему набору в порядкеORDERдляLIMIT. -
digitsЦелочисленный литерал, указывающий количество знаков после запятой при округлении в
PROPORTION. -
NULLУказывает, что агрегирующая функция может вернуть
NULL, даже если все значения параметров — не-NULL. -
classNameИмя встроенного класса значения, возвращаемого
CUSTOM. Если опущено, класс результата выводится из первого основного выражения (либо из первого выраженияORDER, если основной список пуст). -
aggrFuncСтроковый литерал, содержащий имя пользовательской или встроенной в СУБД агрегирующей функции.
-
expr1, ..., exprNОсновные выражения. Для
SUM,PREV,LASTиUNGROUPсписок содержит ровно одно выражение: дляSUMоно суммируется накопительно по окну разбиения; дляPREVиLASTберётся со значения предыдущего и текущего набора соответственно (NULLдля первого набора в случаеPREV); дляUNGROUPоно определяет пропорцию (сPROPORTION) или лимит (сLIMIT). ДляCUSTOMсписок содержит операнды, передаваемыеaggrFunc; список может быть пустым, но тогда блокORDERобязателен. -
groupExpr1, ..., groupExprMСписок группировочных выражений.
-
DESCКлючевое слово. Указывает на обратный порядок просмотра наборов объектов.
-
orderExpr1, ..., orderExprKСписок выражений, определяющих порядок, в котором будут просматриваться наборы объектов. Для определения порядка сначала используется значение первого выражения, затем при равенстве — значение второго и т. д.
-
TOP topExprВ каждом разбиении в вычислении будут участвовать только первые
nзаписей в порядке разбиения, гдеn— значение выраженияtopExpr. -
OFFSET offsetExprВ каждом разбиении первые
mзаписей в порядке разбиения будут пропущены, гдеm— значение выраженияoffsetExpr.
Примеры
// определяет место команды в конференции
CLASS Conference;
conference = DATA Conference (Team);
points = DATA INTEGER (Team);
gamesWon = DATA INTEGER (Team);
place 'Место' (Team team) = PARTITION SUM 1 ORDER DESC points(team), gamesWon(team) BY conference(team);
// строим порядковые индексы объектов в базе по возрастанию их внутренних идентификаторов (то есть в порядке создания)
index 'Номер' (Object o) = PARTITION SUM 1 IF o IS Object ORDER o;
// находит команду, следующую в турнирной таблице по конференции
prevTeam (Team team) = PARTITION PREV team ORDER place(team), team BY conference(team);
// пример пропорционального распределения
CLASS Order;
transportSum 'Транспортные расходы' = DATA NUMERIC[10,2] (Order);
CLASS OrderDetail;
order = DATA Order (OrderDetail) NONULL DELETE;
sum = DATA NUMERIC[14,2] (OrderDetail);
transportSum 'Транспортные расходы по строке' (OrderDetail d) = PARTITION UNGROUP transportSum
PROPORTION STRICT ROUND(2) sum(d)
ORDER d
BY order(d);
// пример распределения с лимитами
discountSum 'Скидка' = DATA NUMERIC[10,2] (Order);
discountSum 'Скидка по строке' (OrderDetail d) =
PARTITION UNGROUP discountSum
LIMIT STRICT sum(d)
ORDER sum(d), d
BY order(d);
;