Aggregate multiple card-many attributes

64 Views Asked by At

With the following data

[
  [:db/add #db/id[db.part/user -1] :Ns/i 0]
  [:db/add #db/id[db.part/user -1] :Ns/ii 1]
  [:db/add #db/id[db.part/user -1] :Ns/ii 2]
  [:db/add #db/id[db.part/user -1] :Ns/ints 1]
  [:db/add #db/id[db.part/user -1] :Ns/ints 2]
]

I can get the 4 Datoms inserted

[:find  ?b ?c ?d
 :where [?a :Ns/i ?b]
        [?a :Ns/ii ?c]
        [?a :Ns/ints ?d]]
==> 
[0 1 2]
[0 2 1]
[0 1 1]
[0 2 2]

I can also get 2 sets

[:find  ?b 
        (distinct ?c) 
        (distinct ?d)  
 :where [?a :Ns/i ?b]
        [?a :Ns/ii ?c]
        [?a :Ns/ints ?d]]

==> [0 #{1 2} #{1 2}]

But if I ask for the sum of one of the sets, I get the sum of all 4 Datoms and not the distinct 2 Datoms for :Ns/ints

[:find  ?b 
        (distinct ?c) 
        (sum ?d)  
 :where [?a :Ns/i ?b]
        [?a :Ns/ii ?c]
        [?a :Ns/ints ?d]]

==> [0 #{1 2} 6]  // would like [0 #{1 2} 3]

And same for 2 sums

[:find  ?b 
        (sum ?c) 
        (sum ?d)  
 :where [?a :Ns/i ?b]
        [?a :Ns/ii ?c]
        [?a :Ns/ints ?d]]

==> [0 6 6]  // would like [0 3 3]

Is there a way I can get the correct sums?

Adding :with to the queries doesn't change the results.

1

There are 1 best solutions below

1
DevEzro On

Okay, then, if I understand correctly, try with this:


    ;; Query to get distinct values for :Ns/ints for each :Ns/i and sum them
    [:find ?b
            (distinct ?c)
            (sum ?d)
     :where [?a :Ns/i ?b]
            [?a :Ns/ii ?c]
            [?a :Ns/ints ?d]
     :with ?a
     :group-by ?b]
    
    ;; Query to get the sum of distinct values for both :Ns/ii and :Ns/ints for each :Ns/i
    [:find ?b
            (sum ?c)
            (sum ?d)
     :where [?a :Ns/i ?b]
            [?a :Ns/ii ?c]
            [?a :Ns/ints ?d]
     :with ?a
     :group-by ?b]