#sql #postgresql #rails-activerecord
#sql #postgresql #rails-activerecord
Вопрос:
У меня есть метод, который вычисляет общий доход из receipts
таблицы. Но в настоящее время при каждом вызове метода выполняется два sql
вызова, возможно ли улучшить sql
выполнение только одного вызова базы данных. Меня устраивает raw sql
, если это необходимо.
def total
Receipt.where(receipt_type: 'income').sum(:amount) - Receipt.where(receipt_type: 'refund').sum(:amount)
end
Основная цель — избежать двух вызовов базы данных. И если разницу можно вычислить только в базе данных, это будет еще лучше. Спасибо.
Ответ №1:
В SQL я бы решил это с помощью
SELECT SUM(amount) FILTER (WHERE receipt_type = 'income')
- SUM(amount) FILTER (WHERE receipt_type = 'refund')
FROM receipt
но я не смог найти эквивалент в ruby. У меня нет опыта работы с этим, но из этого примера, я думаю, должно сработать следующее:
Receipt.select("SUM(amount) FILTER (WHERE receipt_type = 'income') - SUM(amount) FILTER (WHERE receipt_type = 'refund') )
Комментарии:
1. Потрясающе! и спасибо, что попробовали версию ruby. Мне не хватало предложения FILTER из-за моих базовых знаний sql.
2. Это проблема, когда записи о возмещении или доходах отсутствуют, верно?
3. Нет, если ни в одной записи нет
receipt_type
«дохода»,SUM(amount)
просто возвращается 0