Объедините 2 SELECT в один SELECT в моем приложении RAILS - PullRequest
0 голосов
/ 29 декабря 2011

У меня есть таблица ORDEREXECUTIONS, в которой хранятся все выполненные заказы.Это мультивалютное приложение, поэтому в таблице есть два столбца CURRENCY1_ID и CURRENCY2_ID.

Чтобы получить список всех ордеров для конкретной валютной пары (например, EUR / USD), мне нужны строки для получения итогов:

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 равен 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, чтобы оно вызывало толькоодин оператор SQL для MySQL?

Ответы [ 2 ]

1 голос
/ 06 января 2012

Полагаю, это подойдет:

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
0 голосов
/ 06 января 2012

Так что вы могли бы сделать

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 (они не будут отображаться в результатах проверки в консоли, но они должны быть там, если вы проверяете хеш атрибутов или вызываете методы доступа напрямую)

Но в зависимости от ваших индексов это может быть на самом деле медленнее, потому что вы не сможете использовать индексы так эффективно. Кажущееся избыточным условие для currency1_id означает, что это позволит использовать индекс для [currency1_id, created_at]. Делайте тесты до и после - иногда 2 быстрых запроса лучше, чем один медленный!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...