Aggregators
Sometimes you don’t want rows from a table but a value to sum it up. Use aggregators in that case.
Join aggregators
Aggregators can be a join, too.
[{:key :person/id
:type :true-column
:primary-key true
:output [:person/pet-count]} (1)
{:key :person/pet-count
:join-path [:person/id :person-pet/person-id :person-pet/pet-id :pet/id]
:aggregate true
:formula [:count-*]}]
1 | Just like normal joins, join aggregators must be mentioned in
:output elsewhere. |
[{[:person/id 1]
[:person/id
:person/name
:person/pet-count]}]
Table person
:
id | name |
---|---|
1 |
Mary |
2 |
John |
Table pet
:
id | name |
---|---|
10 |
Tom |
20 |
Jerry |
Table person_pet
:
person_id | pet_id |
---|---|
1 |
10 |
1 |
20 |
{[:person/id 1]
{:person/id 1
:person/name "Mary"
:person/pet-count 2}}
With filters and pagination
Aggregators can be used together with filters and pagination!
[{:key :farmers/total
:type :root
:table "farmer"
:aggregate true
:formula [:count-*]}]
Count number of all farmers whose name
starting with "a"
:
`[(:farmers/total {:filter [:like :farmer/name "a%"]})]
Parameterized query:
SELECT COUNT(*) AS `farmers/total` FROM `farmer`
WHERE `farmer`.`name` LIKE ?
parameters:
["a%"]
Aggregators vs Pseudo-columns
An aggregator is meant to produce a single value, while pseudo columns are for adding one or more columns to all rows.
For instance, if you want the value of:
max (`table_a`.`column_x`)
you will need an aggregator:
;; registry
[{:key :your/aggregator
... ;; let it be root or join
:aggregate true
:formula [:max :table-a/column-x]}]
In contrast, if you want the value of:
max (`table_a`.`column_x`, `table_a`.`column_y`)
you will need a pseudo-column:
;; registry
{:key :your/other-column
:type :pseudo-column
:formula [:max :table-a/column-x :table-a/column-y]}
More freedom with S-expressions
You’re free to use whatever s-expression in your aggregator, as long as the final result returned by SQL is a single value.
;; registry
{:key :your/aggregator
... ;; let it be root or join
:aggregate true
:formula
[:/ [:+ [:* 10 [:max :table-a/column-x]]
[:max :table-a/column-y]]
2]}