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

Оператор 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);
;