2012-10-23 42 views
2

我想產生類似下面的使用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

*使用SQL *生成SQL查詢...您剛剛向我們展示了SQL查詢。你能澄清你的要求嗎? – Kermit

+0

@njk用「Ruby's Sequel」替換第二個「SQL」。我已經應用了一個編輯。 – iain

回答

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')))"> 
+0

+1。它讓我的頭部受傷了一分鐘,因爲我從來沒有考慮過在Sequel數據集中使用「注入」,但然後點擊它。做得很好。 –

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'))) 

我看着伊恩的回答,這是基本相同,我的第二個,只有更簡潔;我喜歡它的優雅。

相關問題