如何将一组聚合输出相加并同时格式化其顺序

时间:2016-05-19 10:15:17

标签: mysql

我希望我能问他正确的问题,但我想总结一组汇总输出并同时格式化它的顺序。

样本表:

Entity Type   Value
A      1      200
B      1      500
C      0      350
B      0      150
D      0      200
C      1      100
A      1      50
A      1      350
D      1      100
E      1      150

预期产出:

Entity    diff_positive    diff_negative
A         600
B         350
E         150
C                          250
D                          100
------------------------------
total     500              350

在帮助下,我能够将所有实体和A'类型' 1'然后从结果中减去实体的总和' A'类型' 0'。同时填充表格以显示这种差异的正面或负面。 目前这就是我所拥有的;

select entity,
greatest(sum(case when type = 1 then value else - value end), 0) as diff_positive,
greatest(sum(case when type = 0 then value else - value end), 0) as diff_negative    
from t
group by entity
ORDER BY diff-negative, entity ASC;

当前输出:

Entity    diff_positive    diff_negative
A         600
B         350
E         150
D                          100
C                          250

我要求实体' C'出现在实体' D'正如预期的产出所示。

另外,要获得总数;我试图将Diff()与Diff-Positive和Diff-Negative相加如下。

select entity,
sum(greatest(sum(case when type = 1 then value else - value end), 0) as diff_positive),
sum(greatest(sum(case when type = 0 then value else - value end), 0) as diff_positive)
from t
group by entity;

我收到错误;

#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'diff_positive), sum(greatest(sum(case when type = 0 then value else - value end), 0) as diff_negative)

我有一种感觉,我应该能够从这一点弄明白,但我对mysql来说还是一个新手

2 个答案:

答案 0 :(得分:0)

要获得总数,请使用with rollup。要获得订购,您可以使用order by。 。 。零值将持续到最后:

select entity,
       greatest(sum(case when type = 1 then value else - value end), 0) as diff_positive,
       greatest(sum(case when type = 0 then value else - value end), 0) as diff_negative    
from t
group by entity
order by diff_positive desc, diff_negative asc;

替代order by是:

order by sum(case when type = 1 then value else - value end)

通过使用表达式,您只能使用order by中的一个键。

编辑:

要使汇总生效,请使用两个级别的聚合:

select entity, sum(diff_positive) as diff_positive,
       sum(diff_negative) as diff_negative)
from (select entity,
             greatest(sum(case when type = 1 then value else - value end), 0) as diff_positive,
             greatest(sum(case when type = 0 then value else - value end), 0) as diff_negative    
      from t
      group by entity
     ) e
group by entity with rollup
order by diff_positive desc, diff_negative asc;

外部group by除了rollup以外没有做任何其他事情。

答案 1 :(得分:0)

在评论中,I said

  

虽然为什么value列并不仅仅存储为+ ve / -ve而且删除了type列超出了我。

经过一番讨论,you replied

  

确定。但我对此没有经验,所以这个想法仍然模糊不清。您如何建议我实施这个?

  1. 首先,更新value中的值:

    UPDATE t SET value = -value WHERE type = 0;
    
  2. 其次,删除type列:

    ALTER TABLE t DROP type;
    
  3. 获取应用程序所需的结果,在应用程序代码中执行到演示模型的转换。例如,使用PDO可以执行以下操作:

    $stmt = $pdo->query('
      SELECT   entity, SUM(value) AS diff
      FROM     t
      GROUP BY entity
      ORDER BY diff DESC
    ');
    
    $total_positive = $total_negative = 0;
    
    while ($row = $stmt->fetch()) {
      if ($row['diff'] > 0) {
        // handle positive diff here as before
    
        $total_positive += $row['diff'];
      } else {
        // handle negative diff here as before
    
        $total_negative += $row['diff'];
      }
    }
    
  4. 值得注意的是,在您的旧模型和此模型中,每个entity只能是-ve + ve中的一个。因此,旧模型中的type(严格来说,这个新模型中value的符号)取决于entity - 因此在此表中重复此内容会违反{{3} }。