Grouping & Aggregations
Qubit supports GROUP BY operations with HAVING clauses and aggregate functions through the Group interface.
Basic GROUP BY
Use groupBy() to group entities by a key:
// Group by department and get keys
List<String> departments = personRepository
.groupBy((Person p) -> p.department.name)
.toList();
The Group Interface
The Group<T, K> interface provides access to the grouping key and aggregate functions:
| Method | Description |
|---|---|
|
Returns the grouping key |
|
Counts entities in the group |
|
Counts distinct values for a field |
|
Averages a numeric field (returns Double) |
|
Minimum value of a comparable field |
|
Maximum value of a comparable field |
|
Sums Integer values (returns Long) |
|
Sums Long values (returns Long) |
|
Sums Double values (returns Double) |
Aggregations with GROUP BY
Project groups to DTOs with aggregate values:
List<DeptStats> stats = personRepository
.groupBy((Person p) -> p.department.name)
.select((Group<Person, String> g) -> new DeptStats(
g.key(),
g.count(),
g.avg((Person p) -> p.salary),
g.min((Person p) -> p.salary),
g.max((Person p) -> p.salary)
))
.toList();
HAVING Clause
Use having() to filter groups based on aggregate conditions:
// Only departments with more than 5 employees
List<DeptStats> largeDepts = personRepository
.groupBy((Person p) -> p.department.name)
.having((Group<Person, String> g) -> g.count() > 5)
.select((Group<Person, String> g) -> new DeptStats(
g.key(),
g.count(),
g.avg((Person p) -> p.salary)
))
.toList();
Multiple having() calls combine with AND:
personRepository
.groupBy((Person p) -> p.department.name)
.having((Group<Person, String> g) -> g.count() > 5)
.having((Group<Person, String> g) -> g.avg((Person p) -> p.salary) > 50000)
.selectKey()
.toList();
Sorting Groups
Sort by key or aggregate values:
// Sort by count descending
List<DeptStats> sorted = personRepository
.groupBy((Person p) -> p.department.name)
.sortedDescendingBy((Group<Person, String> g) -> g.count())
.select((Group<Person, String> g) -> new DeptStats(
g.key(), g.count()
))
.toList();