如何查询WHERE(ColA,ColB,ColC)IN((a1,b1,c1),(a2,b2,c2),...)

时间:2015-10-14 15:07:57

标签: ruby-on-rails ruby ruby-on-rails-4 activerecord

如何在Rails4 / ActiveRecord中按多组值找到多条记录?我希望实现以下目标:

SELECT * FROM some_table WHERE (A, B, C) IN ((1, 2, 3), (4, 5, 6), ...)

nsave建议的以下方式完全可以正常工作。

User.where({ name: ["Alice", "Bob"], age: [20, 30, 40]})

将导致

SELECT * FROM users WHERE name IN ('Alice', 'Bob') AND age IN (20, 30, 40)

我需要的是一段导致

的代码

SELECT * FROM users WHERE (name, age) IN (('Alice', 20), ('Bob', 30))

我想搜索包含多组值中的一行的所有行。我怎么能做到这一点?

3 个答案:

答案 0 :(得分:1)

如果我理解正确,那么只需:

User.where({ name: ["Alice", "Bob"], age: [20,30,40] })

答案 1 :(得分:1)

现在回答我自己的问题,因为在使用ActiveRecord 4.2.4时似乎没有像这样的问题的正式方法。

我通过使用一种特别用于查询元组的新方法来扩展AR来解决我的问题:

module ActiveRecord
  class Base
    class << self

      # not really compatible to the rest of ActiveRecord but it works
      # provide parameters like this: symbols_tuple = [ :col1, :col2, :col3 ]
      # and values_tuples = [ [1, 4, 7], [2, 5, 8], [3, 6, 9]]
      # this will result in a SQL statement like SELECT * FROM table WHERE ((col1, col2, col3) IN ((1,4,7),(2,5,8),(3,6,9)))
      def where_tuple(symbols_tuple, values_tuples)
        tuple_size = symbols_tuple.size

        tuple_part = "(#{(['?']*tuple_size).join(',')})"
        in_stmt = "(#{([tuple_part]*values_tuples.size).join(', ')})"
        stmt = "(#{symbols_tuple.map { |sym| sym.to_s }.join(', ')}) IN #{in_stmt}"

        res = where(stmt, *(values_tuples.flatten!))

        return res
      end

    end # end of class << self
  end # end of class Base
end

这并没有真正融入ActiveRecord的常规方法,但至少在我的情况下它能完成这项工作。

如果你能想出一种如何以更优雅的方式解决这类问题的方法,请告诉我。

答案 2 :(得分:0)

您可以执行以下操作:

Foo.where('bar = ? AND baz = ?', 1, 2)

此查询会搜索Foo.bar的{​​{1}} 1的{​​{1}}

查询可以继续,您可以根据需要传递任意数量的条件。您还可以使用其他运营商,例如Foo.baz2。例如,您可以> >=查询Foo.where('bar >= ?', 3)类,其中Foo等级大于或等于3.