我有下表:
+-----+-----------+----------+------------+------+
| 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未被考虑在内,因为idStudent
1已经达到30 hourCourse
idCourse
1和2。
最后,查询解决方案应该如下:
+-----------+-------------+
| idStudent | WeightedAvg |
+-----------+-------------+
| 1 | 66.0000 |
| 3 | 76.6667 |
+-----------+-------------+
有没有办法为此创建内联查询?提前谢谢。
编辑:选择课程时的标准是从最高到最低分。 编辑:当小时30的累积总和小于30时,会包含寄存器。例如,将包含两个20小时的寄存器(总和40),以下不是。
答案 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;