You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/source/en/sequence-aggregation.md
+9-18Lines changed: 9 additions & 18 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -21,17 +21,15 @@ inline fun <E : Any, T : BaseTable<E>, C : Any> EntitySequence<E, T>.aggregateCo
21
21
It's a terminal operation, and it accepts a closure as its parameter, in which we need to return an aggregate expression. Ktorm will create an aggregate query, using the current filter condition and selecting the aggregate expression specified by us, then execute the query and obtain the aggregate result. The following code obtains the max salary in department 1:
22
22
23
23
```kotlin
24
-
val max = database
25
-
.sequenceOf(Employees, withReferences =false)
24
+
val max = database.employees
26
25
.filter { it.departmentId eq 1 }
27
26
.aggregateColumns { max(it.salary) }
28
27
```
29
28
30
29
If we want to aggregate two or more columns, we can change to `aggregateColumns2` or `aggregateColumns3`, then we need to wrap our aggregate expressions by `Pair` or `Triple` in the closure, and the function's return type becomes `Pair<C1?, C2?>` or `Triple<C1?, C2?, C3?>`. The example below obtains the average and the range of salaries in department 1:
Obviously, `groupBy` is a terminal operation, it will execute the internal query and iterate the query results right now, then extract a grouping key by the `keySelector` closure for each element, finally collect them into the groups they are belonging to. The following code obtains all the employees and groups them by their departments:
75
73
76
74
```kotlin
77
-
val employees = database.sequenceOf(Employees).groupBy { it.department.id }
75
+
val employees = database.employees.groupBy { it.department.id }
78
76
```
79
77
80
78
Here, the type of `employees` is `Map<Int, List<Employee>>`, in which the keys are departments' IDs, and the values are the lists of employees belonging to the departments. Now we have the employees' data for every department, we are able to do some aggregate calculations over the data. The following code calculates the average salaries for each department:
@@ -91,7 +88,6 @@ But, unfortunately, the aggregate calculation here is performed inside the JVM,
91
88
```sql
92
89
select*
93
90
from t_employee
94
-
left join t_department _ref0 ont_employee.department_id=_ref0.id
95
91
```
96
92
97
93
Here, the only thing we need is the average salaries, but we still have to obtain all the employees' data from the database. The performance issue may be intolerable in most cases. It'll be better for us to generate proper SQLs using *group by* clauses and aggregate functions, and move the aggregate calculations back to the database. To solve this problem, we need to use the `groupingBy` function.
@@ -130,8 +126,7 @@ inline fun <E : Any, T : BaseTable<E>, K : Any, C : Any> EntityGrouping<E, T, K>
130
126
Similar to the `aggregateColumns` of `EntitySequence`, it's a terminal operation, and it accepts a closure as its parameter, in which we should return an aggregate expression. Ktorm will create an aggregate query, using the current filter condition and the grouping key, selecting the aggregate expression specified by us, then execute the query and obtain the aggregate results. Its return type is `Map<K?, C?>`, in which the keys are our grouping keys, and the values are the aggregate results for the groups. The following code obtains the average salaries for each department:
131
127
132
128
```kotlin
133
-
val averageSalaries = database
134
-
.sequenceOf(Employees, withReferences =false)
129
+
val averageSalaries = database.employees
135
130
.groupingBy { it.departmentId }
136
131
.aggregateColumns { avg(it.salary) }
137
132
```
@@ -147,8 +142,7 @@ group by t_employee.department_id
147
142
If we want to aggregate two or more columns, we can change to `aggregateColumns2` or `aggregateColumns3`, then we need to wrap our aggregate expressions by `Pair` or `Triple` in the closure, and the function’s return type becomes `Map<K?, Pair<C1?, C2?>>` or `Map<K?, Triple<C1?, C2?, C3?>>`. The following code prints the averages and the ranges of salaries for each department:
@@ -177,17 +171,15 @@ Additionally, Ktorm also provides many convenient helper functions, they are all
177
171
With these functions, we can write the code below to obtain average salaries for each department:
178
172
179
173
```kotlin
180
-
val averageSalaries = database
181
-
.sequenceOf(Employees)
174
+
val averageSalaries = database.employees
182
175
.groupingBy { it.departmentId }
183
176
.eachAverageBy { it.salary }
184
177
```
185
178
186
179
Besides, Ktorm also provides `aggregate`, `fold`, `reduce`, they have the same names as the extension functions of `kotlin.collections.Grouping`, and the usages are totally the same. The following code calculates the total salaries for each department:
187
180
188
181
```kotlin
189
-
val totalSalaries = database
190
-
.sequenceOf(Employees)
182
+
val totalSalaries = database.employees
191
183
.groupingBy { it.departmentId }
192
184
.fold(0L) { acc, employee ->
193
185
acc + employee.salary
@@ -197,8 +189,7 @@ val totalSalaries = database
197
189
Of course, if only the total salaries are needed, we don’t have to write codes in that way. Because the performance is really poor, as all employees are obtained from the database. Here we just show you the usage of the `fold` function. It’s better to use `eachSumBy`:
0 commit comments