3

Ruby の Sequel を使用して、次のような SQL クエリを生成したいと考えています。

SELECT * FROM Objects WHERE (color = "red" AND shape = "triangle") OR 
                            (color = "blue" AND shape = "square") OR
                            (color = "green" AND shape = "circle")

次のようなことができるように、条件のリストからプログラムでこのクエリを作成したいと考えています。

conditions = [[[:color, "red"], [:shape, "triangle"]],
              [[:color, "blue"], [:shape, "square"]],
              [[:color, "green"], [:shape, "circle"]]]
DB[:Users].where(conditions.sql_or)

その正確な形式に従う必要はありませんが、プログラムで条件を構築できるようにしたいので、このクエリを手動で構築できるだけでは不十分です。

4

2 に答える 2

2

これを試して:

conditions = [ 
               {:color => "red", :shape => "triangle"},
               {:color => "blue", :shape => "square"},
               {:color => "green", :shape => "circle"}
             ]

head, *tail = *conditions

tail.inject(DB[:Users].filter(head)){|mem,obj| mem.or(obj) }

私は得る:

=> #<Sequel::Postgres::Dataset: "SELECT * FROM \"Users\" WHERE (((\"color\" = 'red') AND (\"shape\" = 'triangle')) OR ((\"color\" = 'blue') AND (\"shape\" = 'square')) OR ((\"color\" = 'green') AND (\"shape\" = 'circle')))">
于 2012-10-23T19:00:57.887 に答える
1

これは、別の SQL クエリを使用して同等の結果を返すと思います。

DB[:Objects].where('(color, shape) in ?', conditions.sql_value_list).sql
=> "SELECT * FROM `Objects` WHERE ((color, shape) in (('red', 'triangle'), ('blue', 'square'), ('green', 'circle')))"

sql_value_listhttp://sequel.rubyforge.org/rdoc/classes/Array.htmlに記載されています

それ以外の場合は次を使用します。

objects = DB[:Objects].where(conditions[0])
conditions[1 .. -1].each { |c| objects = objects.or(c) }

結果は次のとおりです。

SELECT * FROM `Objects` WHERE (((`color` = 'red') AND (`shape` = 'triangle')) OR ((`color` = 'blue') AND (`shape` = 'square')) OR ((`color` = 'green') AND (`shape` = 'circle')))

私はIainの答えを見ていましたが、基本的には2番目の答えと同じですが、より簡潔です。私はその優雅さが好きです。

于 2012-10-23T19:54:10.173 に答える