16.5. Grouping and Aggregation Operations
groupBy(field)
multiple times. The order of grouping fields is not relevant.
Example 16.5. Grouping Books by author and counting them
Query query = queryFactory.from(Book.class) .select(Expression.property("author"), Expression.count("title")) .having("title").like("%engine%") .groupBy("author") .toBuilder() .build(); // results.get(0)[0] will contain the first matching entry's author // results.get(0)[1] will contain the first matching entry's title List<Object[]> results = query.list();
The following aggregation operations may be performed on a given field:
avg()
- Computes the average of a set ofNumber
s, represented as aDouble
. If there are no non-null values the result is null instead.count()
- Returns the number of non-null rows as aLong
. If there are no non-null values the result is 0 instead.max()
- Returns the greatest value found in the specified field, with a return type equal to the field in which it was applied. If there are no non-null values the result is null instead.Note
Values in the given field must be of typeComparable
, otherwise anIllegalStateException
will be thrown.min()
- Returns the smallest value found in the specified field, with a return type equal to the field in which it was applied. If there are no non-null values the result is null instead.Note
Values in the given field must be of typeComparable
, otherwise anIllegalStateException
will be thrown.sum()
- Computes and returns the sum of a set ofNumber
s, with a return type dependent on the indicated field's type. If there are no non-null values the result is null instead.The following table indicates the return type based on the specified field.Table 16.1. Sum Return Type Field Type Return Type Integral (other than BigInteger
)Long
Floating Point Double
BigInteger
BigInteger
BigDecimal
BigDecimal
The following cases items describe special use cases with projection queries:
- A projection query in which all selected fields are aggregated and none is used for grouping is legal. In this case the aggregations will be computed globally instead of being computed per each group.
- A grouping field can be used in an aggregation. This is a degenerated case in which the aggregation will be computed over a single data point, the value belonging to current group.
- A query that selects only grouping fields but no aggregation fields is legal.
Aggregation queries can include filtering conditions, like usual queries, which may be optionally performed before and after the grouping operation.
groupBy
method will be applied directly to the cache entries before the grouping operation is performed. These filter conditions may refer to any properties of the queried entity type, and are meant to restrict the data set that is going to be later used for grouping.
groupBy
method will be applied to the projection that results from the grouping operation. These filter conditions can either reference any of the fields specified by groupBy
or aggregated fields. Referencing aggregated fields that are not specified in the select
clause is allowed; however, referencing non-aggregated and non-grouping fields is forbidden. Filtering in this phase will reduce the amount of groups based on their properties.