Aggregate Functions
Saferis provides type-safe aggregate functions with the selectAggregate method.
Basic Aggregates
Query[EventRow]
.where(_.instanceId)
.eq("instance-1")
.selectAggregate(_.sequenceNr)(_.max)
.build
.sqlselect max("aggregate_event_rows_ref_1"."sequenceNr") from "aggregate_event_rows" as "aggregate_event_rows_ref_1" where "aggregate_event_rows_ref_1"."instanceId" = $1Query[EventRow]
.where(_.instanceId)
.eq("instance-1")
.selectAggregate(_.amount)(_.min)
.build
.sqlselect min("aggregate_event_rows_ref_1"."amount") from "aggregate_event_rows" as "aggregate_event_rows_ref_1" where "aggregate_event_rows_ref_1"."instanceId" = $1Query[EventRow]
.where(_.instanceId)
.eq("instance-1")
.selectAggregate(_.amount)(_.sum)
.build
.sqlselect sum("aggregate_event_rows_ref_1"."amount") from "aggregate_event_rows" as "aggregate_event_rows_ref_1" where "aggregate_event_rows_ref_1"."instanceId" = $1Query[EventRow]
.where(_.instanceId)
.eq("instance-1")
.selectAggregate(_.sequenceNr)(_.count)
.build
.sqlselect count("aggregate_event_rows_ref_1"."sequenceNr") from "aggregate_event_rows" as "aggregate_event_rows_ref_1" where "aggregate_event_rows_ref_1"."instanceId" = $1Query[EventRow]
.where(_.instanceId)
.eq("instance-1")
.selectAggregate(countAll)
.build
.sqlselect count(*) from "aggregate_event_rows" as "aggregate_event_rows_ref_1" where "aggregate_event_rows_ref_1"."instanceId" = $1COALESCE for Default Values
Handle NULL results from aggregates with coalesce:
Query[EventRow]
.where(_.instanceId)
.eq("instance-1")
.selectAggregate(_.sequenceNr)(_.max.coalesce(0L))
.build
.sqlselect coalesce(max("aggregate_event_rows_ref_1"."sequenceNr"), $1) from "aggregate_event_rows" as "aggregate_event_rows_ref_1" where "aggregate_event_rows_ref_1"."instanceId" = $2Query[EventRow]
.where(_.instanceId)
.eq("nonexistent")
.selectAggregate(_.amount)(_.sum.coalesce(BigDecimal(0)))
.build
.sqlselect coalesce(sum("aggregate_event_rows_ref_1"."amount"), $1) from "aggregate_event_rows" as "aggregate_event_rows_ref_1" where "aggregate_event_rows_ref_1"."instanceId" = $2Executing Aggregate Queries
Use queryValue[T] to get the aggregate result:
(
for
_ <- ddl.createTable[EventRow](ifNotExists = true)
_ <- dml.insert(EventRow(-1, "test", 1L, BigDecimal(100)))
_ <- dml.insert(EventRow(-1, "test", 5L, BigDecimal(200)))
_ <- dml.insert(EventRow(-1, "test", 3L, BigDecimal(150)))
maxSeq <- Query[EventRow]
.where(_.instanceId)
.eq("test")
.selectAggregate(_.sequenceNr)(_.max.coalesce(0L))
.queryValue[Long]
total <- Query[EventRow]
.where(_.instanceId)
.eq("test")
.selectAggregate(_.amount)(_.sum)
.queryValue[BigDecimal]
count <- Query[EventRow]
.where(_.instanceId)
.eq("test")
.selectAggregate(countAll)
.queryValue[Long]
yield (maxSeq, total, count)
).either
.provideLayer(DocsTransactor.layer)Right((Some(5),Some(450),Some(3)))Available Aggregate Functions
| Function | Description |
|---|---|
_.max | Maximum value |
_.min | Minimum value |
_.sum | Sum of values |
_.count | Count of non-null values |
_.avg | Average value |
countAll | Count all rows (COUNT(*)) |
.coalesce(default) | Return default if NULL |