在我的RAILS应用程序中将2个SELECT组合成一个SELECT

时间:2011-12-29 04:54:07

标签: mysql ruby-on-rails-3 performance

我有一个名为ORDEREXECUTIONS的表,用于存储已执行的所有订单。它是一个多货币应用程序,因此该表有两列CURRENCY1_ID和CURRENCY2_ID。

要获取特定货币对(例如欧元/美元)的所有订单清单,我需要排列以获得总数:

v = Orderexecution.where("is_master=1 and currency1_id=? and currency2_id=? and created_at>=?",c1,c2,Time.now()-24.hours).sum("quantity").to_d
v+= Orderexecution.where("is_master=1 and currency1_id=? and currency2_id=? and created_at>=?",c2,c1,Time.now()-24.hours).sum("unitprice*quantity").to_d

请注意,我的SUM()公式根据货币的顺序而有所不同。 例如如果我想要货币对USD的总订购数量,则执行(假设USD的货币ID为1,EUR为2。

v = Orderexecution.where("is_master=1 and currency1_id=? and currency2_id=? and created_at>=?",1,2,Time.now()-24.hours).sum("quantity").to_d
v+= Orderexecution.where("is_master=1 and currency1_id=? and currency2_id=? and created_at>=?",2,1,Time.now()-24.hours).sum("unitprice*quantity").to_d

如何在RoR中编写它,以便它只触发一个到MySQL的单个SQL语句?

2 个答案:

答案 0 :(得分:1)

我想这会做:

v = Orderexecution.where("is_master=1 
                           and ( (currency1_id, currency2_id) = (?,?)
                              or (currency1_id, currency2_id) = (?,?)
                               )
                           and created_at>=?"
                        ,c1, c2, c2, c1, Time.now()-24.hours
                        )
                  .sum("CASE WHEN currency1_id=? 
                               THEN quantity 
                             ELSE unitprice*quantity 
                        END"
                      ,c1 
                      )
                  .to_d

答案 1 :(得分:0)

所以你可以做到

SELECT SUM(IF(currency1_id = 1 and currency2_id = 2, quantity,0)) as quantity,
     SUM(IF(currency2_id = 1 and currency1_id = 2, unitprice * quantity,0)) as unitprice _quantity from order_expressions
WHERE created_at > ? and (currency1_id = 1 or currency1_id = 2)

如果将其插入find_by_sql,您应该返回一个对象,其中包含2个属性quantityunitprice_quantity(它们不会出现在控制台中的inspect输出中但如果你检查属性哈希或直接调用访问器方法,它们应该在那里)

但是根据您的索引可能实际上会更慢,因为它可能无法有效地使用索引。 currency1_id上似乎多余的条件意味着这可以使用[currency1_id, created_at]上的索引。做之前和之后的基准 - 有时2个快速查询比慢速查询好!