将表A的SUM添加到表B的单个列中

时间:2018-10-02 08:18:34

标签: ruby-on-rails sqlite ruby-on-rails-4

简化术语:

Table A
ID | City | Amount
1 | Atlanta | 100
2 | Atlanta | 200
3 | Utah | 300

Table B
ID | City | Modifier
1 | Atlanta | 50
2 | Utah | 60

步骤:

  1. 计算Atlanta

  2. 表A中金额的总和:

  

100 + 200

  1. 将修饰符添加到#1的结果中:
  

50 +(100 + 200)

输出:

  

350

编辑:

我只能得到表A的总和。我不知道如何在不将修饰符添加到表A的每条记录的情况下添加修饰符:

TableA.joins("
  LEFT JOIN TableB ON TableB.city = TableA.city
").select("
  SUM(TableA.amount) + TableB.modifier
").where("
  TableA.city = 'Atlanta'
").group("
  TableA.city
")

2 个答案:

答案 0 :(得分:2)

目前尚不清楚您需要什么。而且,对此类事情使用Arel方法链会使它们变得更加复杂。

如果您想要一个包含TableA中的金额之和加上TableB中的金额之和的城市列表,则可以使用单个SQL查询获得。

(假设您使用的是PostgreSQL):

SELECT T.city, COALESCE(T.amount, 0) + COALESCE(B.modifier, 0) AS modified_sum
FROM (SELECT city, SUM(amount) AS amount FROM table_a GROUP BY city) T
    FULL JOIN table_b B ON B.city = T.city;

http://rextester.com/OSS97422

如果您具有模型TableA和TableB,则查询可以转换为Rails方法:

TableA.find_by_sql "SELECT T.city, COALESCE(T.amount, 0) + COALESCE(B.modifier, 0) AS amount
    FROM (SELECT city, SUM(amount) AS amount FROM #{TableA.table_name} GROUP BY city) T
        FULL JOIN #{TableB.table_name} B ON B.city = T.city"

如果您的任务是获取“亚特兰大”的价值,那么方法调用将是:

TableA.find_by_sql ["SELECT T.city, COALESCE(T.amount, 0) + COALESCE(B.modifier, 0) AS amount
    FROM (SELECT city, SUM(amount) AS amount FROM #{TableA.table_name} GROUP BY city) T
        LEFT JOIN #{TableB.table_name} B ON B.city = T.city
    WHERE T.city = :city", { city: 'Atlanta' }]

在第一种情况下,请注意FULL JOIN,在后一种情况下,请注意LEFT JOIN。对于第一个查询,FULL JOIN从两个表A和B中提供城市。对于第二个查询,查询在表A中查找“亚特兰大”。

如果您的任务不同,则可以根据需要修改这些调用。

答案 1 :(得分:1)

使用原始SQL可以很容易地回答问题:

with amount_by_city as (
select
         city
       , sum(amount) as total_amount
    from table_a
group by city
)
select
    b.city
  , a.total_amount + b.modifier
from table_b b
join amount_by_city a on b.city = a.city

RoR可以运行原始的SQL语句,如Source中所述。除非您有其他需求,否则只需使用原始SQL。

Rails raw SQL example