2010-12-02 202 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

相關問題