Skip to content

Commit f489bc5

Browse files
MattSchuragoerler
andauthored
Java: Aggregation API (#2125)
Co-authored-by: Adrian Görler <adrian.goerler@sap.com>
1 parent 1361118 commit f489bc5

File tree

1 file changed

+77
-3
lines changed

1 file changed

+77
-3
lines changed

java/working-with-cql/query-api.md

Lines changed: 77 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -621,7 +621,22 @@ Select.from("bookshop.Books")
621621
b.get("title").startsWith("Wuth")));
622622
```
623623

624-
### Grouping
624+
625+
### Aggregating Data { #aggregating }
626+
627+
You can aggregate data in two ways:
628+
629+
- **Aggregate the current entity:** Use [aggregate functions](#aggregation-functions) like `sum` in the columns clause of your `Select` statement, usually together with [groupBy](#group-by), to summarize or group data.
630+
631+
- **Aggregate associated entities:** Use dedicated aggregation methods to calculate values over to-many associations directly in your queries. See [Aggregating over Associations](#aggregating-associations).
632+
633+
634+
#### Aggregation Functions { #aggregation-functions }
635+
636+
Use [aggregation functions](/guides/databases#aggregate-functions) to calculate minimums, maximums, totals, averages, and counts of values. You can use them in *columns* of `Select` statements to include the aggregated values in the result set, or in the [having](#having) clause to filter based on aggregated values.
637+
638+
639+
#### Grouping { #grouping }
625640

626641
The Query Builder API offers a way to group the results into summarized rows (in most cases these are aggregate functions) and apply certain criteria on it.
627642

@@ -635,7 +650,7 @@ Let's assume the following dataset for our examples:
635650
|103 |Hugo |
636651
|104 |Smith |
637652

638-
#### Group By
653+
##### Group By { #group-by }
639654

640655
The `groupBy` clause groups by one or more elements and usually involves aggregate [functions](query-api#scalar-functions), such as `count`, `countDistinct`, `sum`, `max`, `avg`, and so on. It returns one row for each group.
641656

@@ -658,7 +673,7 @@ If we execute the query on our dataset, we get the following result:
658673
|Hugo |1 |
659674

660675

661-
#### Having
676+
##### Having { #having }
662677

663678
To filter the [grouped](#group-by) result, `having` is used. Both, `having` and `where`, filter the result before `group by` is applied and can be used in the same query.
664679

@@ -678,6 +693,65 @@ If we execute the query on our dataset, we get the following result:
678693
|Smith |3 |
679694

680695

696+
#### Aggregating over Associations <Beta /> { #aggregating-associations }
697+
698+
Use the aggregation methods `min`, `max`, `sum`, and `count` to calculate minimums, maximums, totals, and counts of values of associated entities directly in your CQL queries. You can use these aggregation methods in *columns* to include the aggregated values in the result set, or in the *where* clause to filter the result set based on aggregated values.
699+
700+
::: tip
701+
Use [infix filters](/cds/cql#with-infix-filters) to aggregate only a subset of a (to-many) association.
702+
:::
703+
704+
##### min
705+
706+
Find the minimum value of an element in a collection.
707+
708+
```java
709+
Select.from(ORDERS).columns(
710+
o -> o.id(),
711+
o -> o.items()
712+
.filter(i -> i.amount().gt(0)) // optional filter
713+
.min(i -> i.amount()).as("minAmount")
714+
);
715+
```
716+
717+
This query selects each order’s id and the minimum item amount greater than 0 as "minAmount".
718+
719+
##### max
720+
721+
Find the maximum value of an element in a collection.
722+
723+
```java
724+
Select.from(ORDERS)
725+
.where(o -> o.items().max(i -> i.amount()).gt(100));
726+
```
727+
728+
This query selects all orders where the maximum item amount is greater than 100.
729+
730+
##### sum
731+
732+
Calculate the total of a numeric element across related entities.
733+
734+
```java
735+
Select.from(ORDERS).columns(
736+
o -> o.id(),
737+
o -> o.items().sum(i -> i.amount().times(i.price())).as("orderTotal")
738+
);
739+
```
740+
741+
This query selects each order's id and the total order amount (sum of amount times price) as "orderTotal".
742+
743+
##### count
744+
745+
Count non-null values of an element in a collection.
746+
747+
```java
748+
Select.from(ORDERS)
749+
.where(o -> o.items().count(i -> i.discount()).gt(0));
750+
```
751+
752+
This query selects all orders where at least one item has a discount.
753+
754+
681755
### Ordering and Pagination
682756

683757
The Query Builder API allows to specify the sort order of query results. The _sort specification_ governs, according to which elements the result is sorted, and which sort order (ascending or descending) is applied.

0 commit comments

Comments
 (0)