1

我正在学习 Datalog/DataScript/Datomic。为此,我在 DataScript 上设置了一个简单的分类帐数据库来使用。到目前为止,它基本上由一组帐户和一个具有属性的记录列表:entry.record/account:entry.record/amount. 现在,我试图通过将:entry.record/amount每个帐户的所有值相加来获得所有帐户的余额。此查询为我提供了在分类帐上有记录的所有帐户的余额:

  (d/q '[:find ?account ?account-name (sum ?amount)
     :with ?record
     :in $
     :where [?account :account/name ?account-name]
            [?record :entry.record/account ?account]
            [?record :entry.record/amount ?amount]]
   @conn)

但是我有一些帐户仍然没有注册任何记录,并且它们没有出现在这里。我想进行一个包含它们的查询,并以 0 值列出。我一直在玩or-join并将missing?这些帐户包含在查询中,但我不知道如何将帐户的金额设为 0。例如,这个查询:

  (d/q '[:find ?account ?account-name (sum ?amount)
     :with ?record
     :in $
     :where [?account :account/name ?account-name]
     (or-join [?record]
              (and [?record :entry.record/account ?account]
                   [?record :entry.record/amount ?amount])
              [(missing? $ ?record :entry.record/account)])]
   @conn)

由于can't assign a value toQuery for unknown vars: [?amount]的第二部分,消息引发异常。or-join?amount

4

1 回答 1

1

Datomic 的 Datalog 绝对不适合这种聚合。我的建议确实是使用 or-join 以发出零数量:

[:find ?account ?account-name (sum ?amount)
 :with ?sum-term
 :in $
 :where [?account :account/name ?account-name]
 (or-join [?account ?amount ?sum-term]
   (and
     [?sum-term :entry.record/account ?account]
     [?sum-term :entry.record/amount ?amount])
   (and
     [(identity ?account) ?sum-term]
     [(ground 0) ?amount]))]

另请参阅:Datomic 聚合:计数相关实体而不会丢失零计数结果

于 2021-06-14T13:00:03.003 回答