按参数数组选择所有记录

时间:2015-02-21 08:57:26

标签: sql ruby-on-rails postgresql

我从POST请求中收到一组参数,它们如下所示:

    Parameters: 
     {"search"=>
      { "minor"=>["1", "1"], "major"=>["1", "2"], "proximity_uuid"=>
        ["12345453453", "12345453453"]
      }
    }

这意味着我要求两件物品:

一个有params:

minor:1

专业:1

prox_uuid: 12345453453

和第二个:

minor:1

专业:2

prox_uuid: 12345453453

正如您可能猜到的,我需要从DB中选择与这些条件完全匹配的项目。

我使用以下查询:

selectbeacon = Beacon.includes(:ads, :venue).where('minor IN (?) 
and major IN (?) and proximity_uuid IN (?)', params[:search][:minor], 
params[:search][:major], params[:search][:proximity_uuid])

然而,问题是它选择了至少匹配一个条件的所有记录,但我需要匹配所有三个。

作为最终结果,我正在生成复杂的JSON响应。

我该如何调整查询?

提前谢谢你,

罗马

2 个答案:

答案 0 :(得分:1)

set1 = [:minor, :major, :proximity_uuid].map { |i| params[:search][i][0] }
set2 = [:minor, :major, :proximity_uuid].map { |i| params[:search][i][-1] }

查询

Beacon.includes(:ads, :venue)
      .where("(minor = ? and major = ? and proximity_uuid = ?) or
              (minor = ? and major = ? and proximity_uuid = ?)",
               *set1, *set2       
             )

在我的控制台玩了一段时间之后,我找到了另一种写上述查询的方法:

Beacon.includes(:ads, :venue)
      .where("(minor, major, proximity_uuid) 
             IN (values(?,?,?),(?,?,?))", *set1, *set2
            )

控制台中测试:

Loading development environment (Rails 4.1.1)
[1] pry(main)> Pet.all
  Pet Load (0.7ms)  SELECT "pets".* FROM "pets"
=> [#<Pet id: 6, animals: 1, created_at: "2015-02-21 10:40:19", updated_at: "2015-02-21 10:40:19", name: "Tilly">,
 #<Pet id: 7, animals: 0, created_at: "2015-02-21 10:40:31", updated_at: "2015-02-21 10:40:54", name: "Xav">,
 #<Pet id: 5, animals: 1, created_at: "2015-02-19 18:27:28", updated_at: "2015-02-21 10:41:06", name: "Mua">]
[2] pry(main)> Pet.where("(id, animals) IN (values(?,?),(?,?))",6,1,5,1)
  Pet Load (1.3ms)  SELECT "pets".* FROM "pets"  WHERE ((id, animals) IN (values(6,1),(5,1)))
=> [#<Pet id: 6, animals: 1, created_at: "2015-02-21 10:40:19", updated_at: "2015-02-21 10:40:19", name: "Tilly">,
 #<Pet id: 5, animals: 1, created_at: "2015-02-19 18:27:28", updated_at: "2015-02-21 10:41:06", name: "Mua">]

答案 1 :(得分:0)

在玩了一段时间后,在我的朋友的帮助下,这是解决方案:

POST参数应如下所示:

search[0][minor] = 1
search[0][major] = 1
search[0][proximity_uuid] = 1111

...

和查询应该是:

result = params["search"].inject([]) { | result, (key, item) | result | Beacon.includes(:ads, :venue).where('minor=? and major=? and proximity_uuid=?', item["minor"], item["major"], item["proximity_uuid"]) }