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

key1 は 1 と 2でidStudentすでに 30 に達しているため、2 は考慮されません。hourCourseidCourse

最後に、クエリ ソリューションは次のようになります。

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

これに対してインラインクエリを作成する方法はありますか? 前もって感謝します。

編集:コースを選択する際の基準は、最高点から最低点までです。 編集: hourCourse の累積合計が 30 未満の場合、レジスターが含まれます。たとえば、それぞれ 20 時間の 2 つのレジスターが含まれ (合計 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 に答える