honeysql merge-where 构建大型查询

Posted

技术标签:

【中文标题】honeysql merge-where 构建大型查询【英文标题】:honeysql merge-where building a large query 【发布时间】:2016-05-15 00:55:40 【问题描述】:

我正在尝试使用 honeysql 以编程方式构建查询,并在我进行时添加 where 子句。

来自 python 并使用 sqlalchemy,我可以执行以下操作:

In [3]: query = model.Account.query
In [4]: query = query.filter_by(id=1)
In [5]: query = query.filter_by(email='abc@foo.com')
In [6]: query = query.filter_by(username='someuser')
In [7]: query = query.filter_by(is_active=1)
In [8]: printquery(query)

SELECT *
FROM account
WHERE account.id = 1 AND account.email = 'abc@foo.com' 
      AND account.username = 'someuser' AND account.is_active = 1

但是,使用 honeysql,我的 where 子句不是那么干净。

user=> (require '[honeysql.core :as sql])
user=> (require '[honeysql.helpers :refer :all])
user=> (->
  #_=>   (select :*)
  #_=>   (from :test)
  #_=>   (merge-where [:= :a 1])
  #_=>   (merge-where [:= :b 2])
  #_=>   (merge-where [:= :c 3])
  #_=>   (merge-where [:= :d 4])
  #_=>   sql/format)

["SELECT * FROM test WHERE (((a = 1 AND b = 2) AND c = 3) AND d = 4)"]

我知道它们在逻辑上是相同的,但随着我开始变得越来越复杂,我开始感到紧张,因为我会得到一些带有额外括号的微妙查询表现得很奇怪,这会导致我问题。

我疯了吗?我应该停止担心并学会爱额外的括号(毕竟是clojure)吗?还是有更好的查询构建模式我不知道?我应该将 where 子句构建为一个大向量,并在最后将它们全部添加到查询映射中吗?

任何建议将不胜感激!

【问题讨论】:

【参考方案1】:

从逻辑的角度来看

a AND b AND c = ( a AND b ) AND c = a AND ( b AND c ).

其中 a、b 和 c 是类似的命题

A = 1

AND 运算符是关联运算符,这意味着括号的放置位置或数量无关紧要,只要命题的顺序保持不变。

制定示例here.

【讨论】:

您好,感谢您的回答。是的,我提到我意识到它们在逻辑上是相同的结果,但我还没有想出一些例子“哦,伙计,在我添加的第 12 个奇怪的子句之后,括号变成了问题!” - 我只是希望有一个更干净的结果。在我的代码中,我已经适应了建立一个子句列表,然后在一个大的[:and] 子句的末尾使用一次merge-where。再次感谢!

以上是关于honeysql merge-where 构建大型查询的主要内容,如果未能解决你的问题,请参考以下文章

HoneySQL 中的联合

HoneySQL 不能处理 WHERE 子句中的复合键?

Honeysql RDBMS 是不可知的吗?

Clojure HoneySQL - 如何在连接后将字符串值聚合到单行中?

C++ 通过使用库提高大型项目的构建速度

C - 构建大型项目期间的多个功能定义