【问题标题】:Sum and Average Percentage Calculation using MYSql使用 MYSql 计算总和和平均百分比
【发布时间】:2017-03-07 11:34:39
【问题描述】:

我有一个Statistics 表,如下所示

parent     key      value   date
MASTER     maths    400     2016-10-12
MASTER     maths    200     2016-10-20
MASTER     maths    350     2016-10-23
MASTER     passed   20%     2016-10-25
MASTER     passed   40%     2016-10-27
MASTER     passed   30%     2016-10-28
MASTER     maths    500     2016-11-12
MASTER     maths    250     2016-11-20 
MASTER     maths    600     2016-11-23 
MASTER     passed   55%     2016-11-25
MASTER     passed   75%     2016-11-27
MASTER     maths    500     2016-12-12
MASTER     maths    250     2016-12-20 
MASTER     maths    600     2016-12-23 
MASTER     passed   70%     2016-12-25
MASTER     passed   65%     2016-12-26
MASTER     passed   45%     2016-12-27
MASTER     maths    500     2017-01-12
MASTER     maths    450     2017-01-20 
MASTER     maths    770     2017-01-23 
MASTER     passed   87%     2017-01-25
MASTER     passed   54%     2017-01-27
MASTER     maths    900     2017-02-12
MASTER     maths    250     2017-02-20 
MASTER     maths    500     2017-02-23 
MASTER     passed   67%     2017-02-25
MASTER     passed   45%     2017-02-27

我需要使用 mysql 显示如下所示的输出

maths  passed   date
950    30%      2016-10
1350   65%      2016-11
1350   60%      2016-12
1720   70.5%    2017-01
1650   56%      2017-02

我写的查询如下

SELECT SUM(CASE WHEN key = 'maths' THEN value ELSE 0 END) AS maths,
       SUM(CASE WHEN key = 'passed' THEN value ELSE 0 END) AS passed 
FROM Statistics
WHERE parent = 'MASTER' GROUP BY MONTH(date) ORDER BY date ASC

但我是通过的总和而不是平均值,也就是说,如果我得到 20%、40%30%,那么我应该得到平均值作为 30%,但对于我上面的查询,我得到了 90%% 也消失在结果中

谁能帮我解决这个问题

【问题讨论】:

  • value是什么字段类型?
  • @McNets 其varchar
  • @McNets 是的,你说得对....30%
  • 你实际上并没有存储 '%' 是吗?!?!?!?!?!
  • 是的,我将 % 存储在表中

标签: mysql sum aggregate average


【解决方案1】:

您必须使用AVG 聚合函数来处理average

改变

SUM(CASE WHEN key = 'passed' THEN value ELSE 0 END) AS passed

AVG(CASE WHEN key = 'passed' THEN value ELSE 0 END) AS passed

% 符号被删除

当运算符与不同类型的操作数一起使用时,会发生类型转换以使操作数兼容。一些转换是隐式发生的。例如,MySQL 会根据需要自动将数字转换为字符串,反之亦然。

要显示% 符号,您可以联系它并提供结果。
查询更改后,可能会帮助您获得所需的结果。

mysql> SELECT DATE_FORMAT( `date`, '%Y-%m' ) AS `month`
    ->      , SUM( CASE `key` WHEN 'maths' THEN `value` ELSE NULL END ) AS `maths`
    ->      -- , SUM( CASE `key` WHEN 'passed' THEN `value` ELSE NULL END ) AS `passed`
    ->      , CONCAT( ROUND( AVG( CASE `key` WHEN 'passed' THEN `value` ELSE NULL END ), 2 ), '%' ) AS `passedAvg`
    ->   FROM Statistics
    ->  WHERE parent = 'MASTER'
    ->  GROUP BY MONTH(`date`)
    ->  ORDER BY `date` ASC;

结果可能是这样的:

+---------+-------+-----------+
| month   | maths | passedAvg |
+---------+-------+-----------+
| 2016-10 |   950 | 30.00%    |
| 2016-11 |  1350 | 65.00%    |
| 2016-12 |  1350 | 60.00%    |
| 2017-01 |  1720 | 70.50%    |
| 2017-02 |  1650 | 56.00%    |
+---------+-------+-----------+

文档参考

  • Type Conversion in Expression Evaluation
    • 当运算符与不同类型的操作数一起使用时,会发生类型转换以使操作数兼容。一些转换是隐式发生的。例如,MySQL 会根据需要自动将数字转换为字符串,反之亦然

【讨论】:

  • 感谢回复,但是通过的百分比好像有误
  • case 子句的else 部分使用NULL 而不是zero。查看更新后的答案。
【解决方案2】:

使用子查询:

要计算 AVG,首先需要知道有多少行“通过”值。

(查看here。)

select yr as `year`, mt as `month`,
       sum(val_maths) as `math`,
       concat(cast((sum(val_passed) / sum(count_passed)) as char(50)), '%')  as `passed`
from (
       select ky, year(dt) as yr, month(dt) as mt,
              if (ky = 'maths', replace(val,'%',''), 0) val_maths,
              if (ky = 'passed', replace(val,'%',''), 0) val_passed,
              if (ky = 'passed', 1, 0) as count_passed    
       from foot
     ) tv
group  by yr, mt
;

| year  | month | maths  | passed |
|-------|-------|--------|--------|
| 2016  | 10    | 950    | 30%    |
| 2016  | 11    | 1350   | 65%    |
| 2016  | 12    | 1350   | 60%    |
| 2017  | 1     | 1720   | 70.5%  |
| 2017  | 2     | 1650   | 56%    |

【讨论】:

  • 就像是《盗尸者入侵》的最后一幕
  • @Strawberry 你看过原版吗?
  • 没有。仅限萨瑟兰。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-03-24
  • 1970-01-01
  • 1970-01-01
  • 2017-10-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多