Đó là một thách thức.
Để giải quyết nó, tôi đã sử dụng một số phương pháp:
- Một Câu lệnh CASE để chuyển đổi vị trí của nhóm trong top 3 thành điểm.
- Đánh số hàng với một biến .
- BÊN TRONG VÀ TRÁI THAM GIA để kết hợp các kết quả lại với nhau.
Truy vấn sau đã được thử nghiệm trên fiddle của bạn và hoạt động:
SELECT t1.`id`, t1.`name`, t1.`group1`,
t1.`section`, t1.`MARKS`, `t_group_points`.`points`
FROM `students` t1
#--- Join groups' points to the students
LEFT JOIN (
(
#---- Join all groups and give points to top 3 avg's groups ----
SELECT `t4`.`group1`, `t_points`.`points`
FROM (SELECT `t3`.`group1`, AVG(`t3`.`marks`) AS `avg`
FROM `students` `t3`
WHERE (`t3`.`section` = 'class1') AND
(`t3`.`group1` IS NOT NULL)
GROUP BY `t3`.`group1`) `t4`
INNER JOIN (
#---------- Select top 3 avarages ----------
(SELECT `top`.`avg`,
#-- Convert row number to points ---
CASE @curRow := @curRow + 1
WHEN '1' THEN 5
WHEN '2' THEN 3
WHEN '3' THEN 1
ELSE NULL END 'points'
FROM (SELECT DISTINCT `t_avg`.`avg`
FROM (SELECT `t2`.`group1`, AVG(`t2`.`marks`) AS `avg`
FROM `students` `t2`
WHERE (`t2`.`section` = 'class1') AND
(`t2`.`group1` IS NOT NULL)
GROUP BY `group1`) `t_avg`
ORDER BY `avg` DESC
LIMIT 0, 3) `top`, (SELECT @curRow:=0) r
) AS `t_points`)
ON (`t_points`.`avg` = `t4`.`avg`)
) AS `t_group_points`)
ON (`t_group_points`.`group1` = `t1`.`group1`)