我想使用Ruby的续集生成如下的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)
它不必遵循那种确切的形式,但我希望能够以编程方式构建条件,因此仅能够手动构造此查询是不够的。
答案 0 :(得分: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')))">
答案 1 :(得分: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_list
记录在http://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的答案,它和我的第二个答案基本相同,只是更简洁;我喜欢它的优雅。