如何选择一组行的sum()和另一个group的sum()

时间:2017-07-18 20:20:30

标签: mysql sql mariadb

我在这里创建了一个包含示例数据和所需结果的SQLfiddle演示:(http://sqlfiddle.com/#!9/dfe73a/7

示例数据

-- table company
+--------+---------+
|   id   |   name  |
+--------+---------+
|   1    |   foo   |
|   2    |   bar   |
+--------+---------+

 -- table sales
+--------+---------------+-----------------+
|   id   |   company_id  |   total_amount  |
+--------+---------------+-----------------+
|   1    |       1       |      300.0      |
|   2    |       1       |      300.0      |
|   2    |       1       |      100.0      |
+--------+---------------+-----------------+

 -- table moves
+--------+---------------+-----------------+
|   id   |   company_id  |   balance_move  |
+--------+---------------+-----------------+
|   1    |       1       |      700.0      |
|   2    |       1       |     -300.0      |
|   2    |       1       |     -300.0      |
+--------+---------------+-----------------+

我需要选择每家公司及其总销售额及其总余额变动总和

期望的结果

+----+----------------------+---------------------+
| id |  total_amount_sum    |   balance_move_sum  |
+----+----------------------+---------------------+
| 1  |         700          |          100        |
+----+----------------------+---------------------+
| 2  |        (null)        |        (null)       |
+----+----------------------+---------------------+

我尝试了这个SQL查询

SELECT 
    company.id,
    sum(total_amount) total_amount_sum,
    sum(balance_move) balance_move_sum
FROM company
     LEFT JOIN sales ON company.id = sales.company_id 
     LEFT JOIN moves ON company.id = moves.company_id
GROUP BY company.id

sum()函数添加了来自联接的所有冗余值,导致总金额2100 (700*3)和净余额300 (100*3)

错误的SQL语句结果

+----+----------------------+---------------------+
| id |  total_amount_sum    |   balance_move_sum  |
+----+----------------------+---------------------+
| 1  |         2100         |          300        |
+----+----------------------+---------------------+
| 2  |        (null)        |        (null)       |
+----+----------------------+---------------------+

是否有可能实现我想要的结果?

2 个答案:

答案 0 :(得分:1)

您通过加入来重复行。

公司:每家公司1排

售后加入:每家公司3行(1x3)

移动加入后:每个公司9行(3x3)

由于这个原因,您最终将public class CustomPluralizer : IPluralizer { public string Pluralize(string identifier) { return Inflector.Pluralize(identifier) ?? identifier; } public string Singularize(string identifier) { return Inflector.Singularize(identifier) ?? identifier; } } 重复三次。

一种解决方法是使用派生表like this,首先计算SUM,然后将结果行1对1连接。

SUM

答案 1 :(得分:0)

使用子查询分别计算两个总和将起作用。

SELECT 
    company.id,
    (Select sum(total_amount) from sales where sales.company_id = company.id) total_amount_sum,
    (Select sum(balance_move) from moves where moves.company_id = company.id) balance_move_sum
FROM company