MySQL:分组后计算平均值(下降最低的两个)

时间:2015-03-15 00:14:57

标签: mysql

伙计们,我下面有一个问题。你能帮帮我解决这个问题吗?非常感谢你。

create table grades ( student varchar(4), assign varchar(4), grade int);

insert into grades values ( 's01','a05',4), ('s01','a06',3),('s02','a04',6),('s02','a05',4),( 's01','a04', 9),( 's02','a01', 9),('s02','a02',8),('s02','a03',9), ( 's01','a01', 9), ( 's01','a02', 7),( 's01','a03', 7) ;

教授保持如上所示的成绩并同意降低两个最低分并取平均分。 向计算机写一个查询,每个学生的平均值如下所示

<SAMPLE_OUTPUT>
+---------+--------------+
| student | avg(O.grade) |
+---------+--------------+
| s01     |       8.0000 |
| s02     |       8.6667 |
+---------+--------------+

3 个答案:

答案 0 :(得分:1)

这样做的一种方法是给每个学生的所有成绩一个等级,然后计算某个等级以上成绩的平均值。派生表中的count(*)用于确保少于三个等级的学生仍然得到平均值(在3个等级的情况下,两个最低等级被淘汰)。

SELECT 
    a.student,     
    AVG(CASE
        WHEN c > 2 AND rank > 2 THEN grade
        WHEN c <= 2 THEN grade
    END) avg
FROM (SELECT student, COUNT(*) c FROM grades GROUP BY student) a
JOIN (
  SELECT 
    student,
    grade, 
    (CASE student
       WHEN @curType THEN @curRow:=@curRow + 1
       ELSE @curRow:=1 AND @curType:=student
     END
    ) + 1 AS rank
  FROM
  grades p, (SELECT @curRow:=0, @curType:='') r
  ORDER BY student , grade ASC
) b ON a.student = b.student
GROUP BY student;

Sample SQL Fiddle

答案 1 :(得分:0)

没有在MySQL中测试,但是应该从这个MSSQL块相对类似(限制而不是顶部,+ 0.0而不是强制转换等) - 我已经为你的表添加了一个ID字段(可以在没有表结构更改的情况下进行复制)使用临时表或WITH..AS语句的预查询:

create table grades (ID INT IDENTITY(1,1), student varchar(4), assign varchar(4), grade int);

insert into grades values ( 's01','a05',4), ('s01','a06',3),('s02','a04',6),('s02','a05',4),( 's01','a04', 9),( 's02','a01', 9),('s02','a02',8),('s02','a03',9), ( 's01','a01', 9), ( 's01','a02', 7),( 's01','a03', 7) 


select distinct i.student,
(select avg(cast(ii.grade as float)) from grades ii where ii.id in (
select top (select 
case count(*)
when 0 then 0
when 1 then 1
when 2 then 2
else count(*) - 2
end
from grades iii where iii.student= i.student) ii.ID from grades ii where  ii.student = i.student order by ii.grade desc))
from grades i

案例陈述是为了确保如果学生有两个或更少的记录,它不会放弃这些成绩 - 对于有三个或更多考试的学生,处理“最差两个被丢弃”的案例系统

如果要求分组,则可以采用不同的方式处理,因为此解决方案不需要分组。

编辑:我正在编辑这个在MySQL中运行,因为这是在MSSQL中,但是另一个答案是在MySQL上工作,所以我只是留在这里用于任何MSSQL窥视同样的问题。

答案 2 :(得分:0)

这是一种方式(但我认为jpw的方法更快)...

SELECT student,MAX(avg_grade) avg_grade
  FROM 
     ( SELECT student, AVG(grade) avg_grade FROM grades GROUP BY student
        UNION ALL
       SELECT a.student
            , AVG(grade) avg_grade
         FROM grades a
         JOIN 
            ( SELECT student
                   , GROUP_CONCAT(grade ORDER BY grade) grades
                FROM grades 
               GROUP 
                  BY student
            ) b
           ON b.student = a.student
        WHERE FIND_IN_SET(a.grade,b.grades) > 2
        GROUP 
           BY student
      ) x
  GROUP
     BY student;