【问题标题】:Calculate 2 average values based on the same column, with different conditions根据同一列,不同条件计算 2 个平均值
【发布时间】:2022-12-02 21:34:51
【问题描述】:

我有下表:

Students (id, name, surname, study_year, department_id)

Courses(id, name)

Course_Signup(id, student_id, course_id, year)

Grades(signup_id, grade_type, mark, date),其中 grade_type 可以是“e”(考试)、“l”(实验室)或“p”(项目)

我想为每个学生显示考试和实验室+项目的平均成绩。

SELECT new_table.id,
       new_table.name,
       new_table.grade_type,
       AVG(new_table.mark) AS "Average Exam Grade"
  FROM (SELECT s.id, c.name, g.grade_type, g.mark
          FROM Students s
          JOIN Course_Signup csn
            ON s.id = csn.student_id
          JOIN Courses c
            ON c.id = csn.course_id
          JOIN Grades g
            ON g.signup_id = csn.id) new_table
 GROUP BY new_table.id, new_table.name, new_table.grade_type
HAVING new_table.grade_type = 'e'
 ORDER BY new_table.id ASC

这将给我每个学生的平均考试成绩,对于他们注册的每门课程,但我还想有一个 AVG(new_table.mark) AS "Average Activity Grade",它将根据 grade_type = 'l' or grade_type = 'p' 列中的分数计算。由于我在HAVING中已经有了考试成绩条件,那么如何为第二个AVG添加第二个条件呢?

【问题讨论】:

    标签: sql oracle join aggregate-functions


    【解决方案1】:

    使用 CASE 表达式在 AVG() 内应用过滤器。

    SELECT
      new_table.id,
      new_table.name,
      AVG(CASE WHEN grade_type  = 'e' THEN new_table.mark END) AS "Average Exam Grade",
      AVG(CASE WHEN grade_type <> 'e' THEN new_table.mark END) AS "Average Activity Grade" 
    FROM
    (
      SELECT s.id, c.name, g.grade_type, g.mark
        FROM Students s
        JOIN Course_Signup csn
             ON s.id = csn.student_id
        JOIN Courses c
             ON c.id = csn.course_id
        JOIN Grades g
             ON g.signup_id = csn.id
    )
      new_table
    WHERE
      new_table.grade_type IN ('e', 'l', 'p')
    GROUP BY
      new_table.id,
      new_table.name
    ORDER BY
      new_table.id ASC
    

    这是有效的,因为...

    • 如果不匹配,CASE 返回NULL(在缺少ELSE 块的情况下)。
    • 聚合(例如AVG())跳过/忽略NULL值。

    笔记;不需要你的子查询,我把它留在因为你有它,但它肯定是多余的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-08-09
      • 2018-11-03
      • 2014-08-09
      • 2021-04-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多