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?
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]}
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.
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 [...]))