【问题标题】:SQL WHERE column = everything (with Active Record)SQL WHERE 列 = 一切(使用 Active Record)
【发布时间】:2021-06-22 13:23:01
【问题描述】:

在 SQL 中,当条件列表 (WHERE) 事先不知道但在代码执行时构建时,您可以创建动态 SQL 语句。所以有时我想要记录的子集(比如匹配数组的 id),但在其他情况下我不希望应用条件(因此返回整个列表)。

在纯SQL中有这个解决方案:Stackoverflow: SQL WHERE column = everything

SELECT * FROM table WHERE id = id

更多:Stackoverflow: Why would someone use WHERE 1=1 AND in a SQL clause?

我将如何使用 Active Record 中的 DSL 来做到这一点?

【问题讨论】:

  • 您忘记添加链接了。
  • 认为您可能点击了“”而不是“发布答案”
  • 抱歉,我添加了链接并改写了问题。

标签: sql ruby-on-rails activerecord


【解决方案1】:

这两种方法都可以:(还有更多)

.where(MyModel.arel_attribut(:id).eq(MyModel.arel_attribute(:id)))
# OR 
.where(Arel.sql("1=1"))

这种“始终为真”的类型条件通常用于存储过程或字符串连接中的查询组装,在这种情况下,您总是有一个 WHERE 子句,但可能没有任何条件,例如

SET @sqlString = 'SELECT * FROM table WHERE 1=1'
IF (@var IS NOT NULL) 
  SET @sqlString = @sqlString + ' AND "column" LIKE ''%' + @var + '%'' '

EXEC (@sqlString) 

# OR

sqlString = "SELECT * FROM table WHERE 1=1" 
if someCondition 
  sqlString = sqlString + " AND column = " + value 
end if 

但所有这些似乎都过时了(尤其是在 Rails 方面)。

ActiveRecord 通过使用一个名为 Arel 的库来避免所有这些,该库在执行之前组装 SQL。

ActiveRecord 提供了一种方便的方法 (#all) 来生成类似的全选概念。您可以只调用MyModel.all,它将返回一个可链接的ActiveRecord::Relation,然后您可以应用条件,或者不应用条件,您可以添加 ORDER BY、GROUP BY、LIMIT、HAVING 等语句,这取决于您在代码中和运行时。

您可以利用这种可链接性来“组装”您认为合适的这些条件,例如

q = MyModel.all 
q.where!(name: "engineersmnky") if find_my_name?

这些调用甚至不必在 SQL 语句顺序中产生“逻辑”意义,因为Arel 知道组合这些语句以形成连贯查询的顺序。例如

MyModel.having("COUNT(column) > 1")
  .order(:name)
  .group(:name)
  .select("name, COUNT(column) AS counter")
  .where(x: 12)
  .limit(2)

从 SQL 的角度来看,这完全是混乱的,但是当实际查询被组装时,它将被正确排序。

【讨论】:

    【解决方案2】:

    在 Rails 中链接 where 子句非常简单

    dataset = User.all
    dataset = dataset.where(name: "John") if filter_name?
    dataset = dataset.where("age > ?", 20) if filter_age?
    dataset
    

    【讨论】:

      猜你喜欢
      • 2013-10-11
      • 2013-01-24
      • 2013-02-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-31
      • 2015-09-17
      • 1970-01-01
      相关资源
      最近更新 更多