3

我有下表:

+-----+-----------+----------+------------+------+
| 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 |
+-----+-----------+----------+------------+------+

使用一个简单的查询,我可以根据hourCourse和向学生展示他们的加权平均值mark

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,因为idStudent1 已经达到 30hourCourseidCourse1 和 2。

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

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

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

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

4

1 回答 1

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

于 2012-06-05T04:16:54.807 回答