0

次のようなクエリを作成するためにsqueelを使用したいと思います。

SELECT * from `table`
WHERE (`field1`, `field2`)
NOT IN (
  (1,"value_a"),
  (2,"value_b"),
  (3,"value_a"),
  ...
)

IN複数のフィールドを配列viaまたはNOT INステートメントと比較する方法があるかどうか知りたいです。

このようなもの(例が機能しないことは承知しています)は、私が言っていることを表現するための良い方法です。

array = [[1,"value_a"], [2,"value_b"], [3, "value_a"]]
Table.where{ (field1 & filed2).not_in array }

このようなことは可能ですか?

アップデート

複数を使用して同じ最終結果を得る方法を知っています... & (a != b) & (c != d) & ...が、それは私が尋ねたものではありませんでした。

4

2 に答える 2

1

もしかしてこの先?

Product.where{
  (title != 'foo') & (description != 'bar') |
  (title != 'baz') & (description != 'xyz')
}

アップデート

除外する値を含む配列が既にある場合は、次のようなスコープを作成できます。

scope :without_title_and_description, lambda{|array| 
  where{array.map{|c1,c2| (title != c1) & (description != c2)}.inject(:|)} 
}

そしてそれを使用します:

array = [[1,"value_a"], [2,"value_b"], [3, "value_a"]]
Product.without_title_and_description(array)

プロデュース:

  Product Load (1.0ms)  SELECT "products".* FROM "products" WHERE (((("products"
."title" != 1 AND "products"."description" != 'value_a') OR ("products"."title"
!= 2 AND "products"."description" != 'value_b')) OR ("products"."title" != 3 AND
 "products"."description" != 'value_a')))
于 2012-12-20T18:21:01.167 に答える
0

主な問題は、Arel (およびその Squeel) がかなり複雑なクエリをサポートしている一方で、このレベルのクエリの複雑さはカバーされていないことです。それを念頭に置いて、SQL に戻り、必要なクエリを手動で構築することが、この機能で Arel 自体を拡張する以外の唯一の解決策です。

existing_compound_ids = [[1,"value_a"],[2,"value_b"],[3, "value_a"]]

compound_collection = existing_compound_ids.inject([]) do |aftermath, member|
  aftermath << "('#{ member[0] }','#{ member[1] }')"
end.join(",")

Table.where("(`tables`.`field1`, `tables`.field2) NOT IN (#{compound_collection})")

次の SQL を構築します。

SELECT `tables`.* from `tables` WHERE ((field1, field2)
NOT IN (('1','value_a'),('2','value_b'),('3','value_a')))

より優れた、またはよりエレガントなソリューションを見たいと思っていますが、まだ見つけていません。

于 2012-12-27T14:33:18.720 に答える