在查询中逐个元素地评估两个数组

时间:2013-12-07 19:26:05

标签: ruby-on-rails-3 postgresql activerecord rails-activerecord

抱歉标题不清楚,但我希望身体清楚地描述我的问题。

所以我有两个数组

title_id: [1542, 1507, 47, 1436, 1527, 3, 173, 1534, 1876, 398]
ref_no: [10, 10, 74, 12, 9, 35, 10, 9, 1, 42]

我想查询第一个数组的索引应该是AND和第二个数组的索引。 就像if:title_id = 1542一样,我想和它一起使用ref_no = 10。等等。

我尝试了以下查询,但这就像乘以凹凸:

Book.where("title_id IN (?) AND ref_no IN (?) ", @ids.map(&:title_id), @ids.map(&:ref_no))

使用:RoR 3,PGSQL

1 个答案:

答案 0 :(得分:1)

这种东西在PostgreSQL的SQL风格中非常简单。你可以像这样加入VALUES表达式:

select books.*
from books b
join (values (1542, 10), (1507, 10), ...) as dt(t, r)
     on b.title_id = dt.t and b.ref_no = dt.r

或者您可以使用ANY和数组或IN:

where (title_id, ref_no) = any (array[(1542,10), (1507, 10), ...])

where (title_id, ref_no) in ((1542,10), (1507, 10), ...)

或者通常的大块OR:

where (title_id = 1542 and ref_no = 10)
   or (title_id = 1507 and ref_no = 10)
   or ...

第二个选项(IN变体):

where (title_id, ref_no) in ((1542,10), (1507, 10), ...)

是您的意图IMO最清晰的匹配。我想不出有任何令人愉快的方式让AR构建它,但是,因为我们处理整数并且不必担心引用和转义问题,我们可以通过一些字符串争论来做到这一点:

trs = @ids.map { |o| "(#{o.title_id.to_i}, #{o.ref_no.to_i})" }.join(',')
Book.where("(title_id, ref_no) in (#{trs})")

你可能用一些难以理解的AREL调用来构造OR版本,但我倾向于放弃AR并直接使用SQL,因为事情变得比婴儿谈话更复杂{AR}想要的a = b and c = d SQL说话。