总和减去最小值的平均值

发布于 2024-10-05 21:30:18 字数 851 浏览 9 评论 0原文

我有一个 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.  

I have an SQL statement that grabs the grades of different activity types (Homework, Quiz, etc), and if there's a drop lowest for that type, it drops, else, it remains. The errors are below as well as the SQL Code.

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

Here are the errors I'm getting:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

宁愿没拥抱 2024-10-12 21:30:18

研究分析函数。 (SO问题Oracle 文档)。

像这样:

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

and:

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

根据您的情况设置分区;我们无法判断,因为您在示例中省略了 FROM ...

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

Look into analytical functions. (SO question, Oracle documentation).

Something like this:

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

and:

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

Set the partitioning with whatever makes sense in your case; we can't tell since you omitted the FROM ... in your example.

You can then use those column aliases in any calculations inside your CASE statement.

夜巴黎 2024-10-12 21:30:18

如果您只需要放弃一个最低成绩(在平局的情况下)

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

If you only need to drop one lowest grade (in case of ties)

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

If you need to drop all lowest grades:

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
飞烟轻若梦 2024-10-12 21:30:18

求和运算符给出一个结果(每组)。最小运算符也是如此。那么 avg-operator 应该聚合什么?

The sum-operator gives one result (per group). The min-operator, too. So over what should the avg-operator aggregate?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文