MySQL中的条件累积SUM

时间:2012-06-05 02:28:17

标签: mysql sql

我有下表:

+-----+-----------+----------+------------+------+
| key | idStudent | idCourse | hourCourse | mark |
+-----+-----------+----------+------------+------+
|   0 |         1 |        1 |         10 |   78 |
|   1 |         1 |        2 |         20 |   60 |
|   2 |         1 |        4 |         10 |   45 |
|   3 |         3 |        1 |         10 |   90 |
|   4 |         3 |        2 |         20 |   70 |
+-----+-----------+----------+------------+------+

使用简单查询,我可以根据hourCoursemark向学生展示加权平均值:

SELECT idStudent,
       SUM( hourCourse * mark ) / SUM( hourCourse ) AS WeightedAvg
  FROM `test`.`test`
  GROUP BY idStudent;
+-----------+-------------+
| idStudent | WeightedAvg |
+-----------+-------------+
|         1 |     60.7500 |
|         3 |     76.6667 |
+-----------+-------------+

但是现在我需要选择寄存器,直到每个学生的hourCourse累积总和达到阈值。例如,对于30 hourCourse的阈值,只应考虑以下寄存器:

+-----+-----------+----------+------------+------+
| key | idStudent | idCourse | hourCourse | mark |
+-----+-----------+----------+------------+------+
|   0 |         1 |        1 |         10 |   78 |
|   1 |         1 |        2 |         20 |   60 |
|   3 |         3 |        1 |         10 |   90 |
|   4 |         3 |        2 |         20 |   70 |
+-----+-----------+----------+------------+------+

key 2未被考虑在内,因为idStudent 1已经达到30 hourCourse idCourse 1和2。

最后,查询解决方案应该如下:

+-----------+-------------+
| idStudent | WeightedAvg |
+-----------+-------------+
|         1 |     66.0000 |
|         3 |     76.6667 |
+-----------+-------------+

有没有办法为此创建内联查询?提前谢谢。

编辑:选择课程时的标准是从最高到最低分。 编辑:当小时30的累积总和小于30时,会包含寄存器。例如,将包含两个20小时的寄存器(总和40),以下不是。

1 个答案:

答案 0 :(得分:4)

您可以在子查询中计算每个idStudent的累计总和,然后只选择累积总和<= 30的结果:

select idStudent,
       SUM( hourCourse * mark ) / SUM( hourCourse ) AS WeightedAvg
from
(
  SELECT t.*,
  case when @idStudent<>t.idStudent
    then @cumSum:=hourCourse
    else @cumSum:=@cumSum+hourCourse
  end as cumSum,
  @idStudent:=t.idStudent
  FROM `test` t,
  (select @idStudent:=0,@cumSum:=0) r
  order by idStudent, `key`
) t
where t.cumSum <= 30
group by idStudent;

演示:http://www.sqlfiddle.com/#!2/f5d07/23