我有一个名为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语句?
答案 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个属性quantity
和unitprice_quantity
(它们不会出现在控制台中的inspect输出中但如果你检查属性哈希或直接调用访问器方法,它们应该在那里)
但是根据您的索引可能实际上会更慢,因为它可能无法有效地使用索引。 currency1_id
上似乎多余的条件意味着这可以使用[currency1_id, created_at]
上的索引。做之前和之后的基准 - 有时2个快速查询比慢速查询好!