2010-12-02 207 views
4

嘿家伙,我有一个SQL语句,用于获取不同活动类型(家庭作业,测验等)的等级,如果该类型的下降最低,则会下降,否则它仍然存在。错误如下以及SQL代码。总和的平均值减最小值

SELECT  Student.firstName, Student.lastName, 'Grades' = 
      CASE 
       WHEN Grades.activityType = 'Homework' THEN 
       CASE WHEN Policy.drop_hw = 1 THEN 
        (AVG(SUM(Grades.grade) - MIN(Grades.grade))) * (Policy.homework/100) 
       ELSE 
        (AVG(Grades.grade) * (Policy.homework/100)) 
       END 
      END, Course.courseNum, Course.sectNum, Grades.activityType 

FROM ... 

下面是我得到的错误:

- Cannot perform an aggregate function on an expression containing an aggregate or a subquery. 
- Column 'Policy.drop_hw' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause. 

回答

3

研究分析功能。 (SO question,Oracle documentation)。

事情是这样的:

AVG(Grades.grade) OVER (PARTITION BY Grades.student_id) AS avg_of_grades 

和:

(AVG(SUM(Grades.grade) - MIN(Grades.grade))) OVER (PARTITION BY Grades.student_id) AS avg_grades_with_drop 

设置与任何有意义的,你的情况划分;我们无法分辨,因为您在示例中省略了FROM ...

然后,您可以在CASE语句中的任何计算中使用这些列别名。

1

如果你只需要去掉一个最低级(在领带的情况下)

SELECT student_id, AVG(grade) 
FROM (
     SELECT *, ROW_NUMBER() OVER (PARTITION BY student_id ORDER BY grade) rn 
     FROM my_tables 
     ) 
WHERE NOT (drop_hw = 1 AND rn = 1) 
GROUP BY 
     student_id 

如果您需要删除所有最低等级:

SELECT student_id, AVG(grade) 
FROM (
     SELECT *, MIN(grade) OVER (PARTITION BY student_id) mingrade 
     FROM my_tables 
     ) 
WHERE NOT (drop_hw = 1 AND grade = mingrade) 
GROUP BY 
     student_id 
0

su m-运算符给出了一个结果(每个组)。最小运算符也是。那么,avg-operator应该聚合什么?

+0

这是一个很好的观点。我没有想到这一点。如果没有总数,我该如何平均总和和最小值? – OneSneakyMofo 2010-12-02 20:43:57

+0

你想做什么?我不明白你想要计算什么。 SUM-MIN有什么意义? – 2010-12-02 20:57:43

相关问题