问题
I want to find persons with minimal age with next query
(d/q '[:find ?name (min ?age)
:in [[?name ?age]]]
[["John" 20]
["Bill" 25]
["Jack" 20]
["Steve" 28]
["Andrew" 30]])
But result is
[["Andrew" 30] ["Bill" 25] ["Jack" 20] ["John" 20] ["Steve" 28]]
How to do that?
回答1:
Instead of chaining the queries together, you could use a subquery (query call from within the query instead of outside of it):
(d/q '[:find ?name ?mage
:in $
:where [(datomic.api/q '[:find (min ?age)
:where [_ :age ?age]]
$) [[?mage]]]
[?name :age ?mage]]
[["John" :age 20]
["Bill" :age 25]
["Jack" :age 20]
["Steve" :age 28]
["Andrew" :age 30]])
Returns:
#{["John" 20] ["Jack" 20]}
回答2:
This would be a pure Datalog solution
(let [db [["John" 20]
["Bill" 25]
["Jack" 20]
["Steve" 28]
["Andrew" 30]]]
(d/q '[:find ?name ?min-age
:in $ ?min-age
:where [?name ?min-age]]
db
(ffirst (d/q '[:find (min ?age)
:in [[?name ?age]]]
db))))
A HAVING clause like in SQL is not part of the query language, but since all queries are executed in the peer, there is no overhead in doing nested queries.
回答3:
You don't need datomic in this case, as you already have in your sequence all the data needed. Use clojure sort instead.
(first (sort-by second [...]))
来源:https://stackoverflow.com/questions/23215114/datomic-aggregates-usage