【问题标题】:Is there a way I can shorten this query?有没有办法可以缩短这个查询?
【发布时间】:2022-01-05 06:59:03
【问题描述】:

我正在解决一项任务,我设法找到了解决方案,但我不确定这是否是编写此查询的最佳方式

SELECT 
    students.studentname,
    CASE 
        WHEN (AVG(courses_student.exam_season_one) +  
              AVG(courses_student.exam_season_two) + 
              AVG(courses_student.degree_season_one) + 
              AVG(courses_student.degree_season_two)) / 4 >= 80 
            THEN 'EXCELLENT'
        WHEN (AVG(courses_student.exam_season_one) +  
              AVG(courses_student.exam_season_two) + 
              AVG(courses_student.degree_season_one) + 
              AVG(courses_student.degree_season_two)) / 4 >= 70 
            THEN 'VERY GOOD'
        WHEN (AVG(courses_student.exam_season_one) +  
              AVG(courses_student.exam_season_two) + 
              AVG(courses_student.degree_season_one) + 
              AVG(courses_student.degree_season_two)) / 4 >= 60 
            THEN 'GOOD'
        WHEN (AVG(courses_student.exam_season_one) +  
              AVG(courses_student.exam_season_two) + 
              AVG(courses_student.degree_season_one) + 
              AVG(courses_student.degree_season_two)) / 4 >= 50 
            THEN 'ACCEPTABLE'
        ELSE 'FAIL'
    END AS GRADE
FROM
    courses_student
JOIN 
    students ON students.student_id = courses_student.student_id
GROUP BY 
    students.studentname

如你所见,我重复了这个:

    WHEN (AVG(courses_student.exam_season_one) +  
          AVG(courses_student.exam_season_two) + 
          AVG(courses_student.degree_season_one) + 
          AVG(courses_student.degree_season_two)) / 4

四次!而且它看起来很乱,所以有没有一种方法可以让它更短,比如只写一次,然后只使用一个单词? (我试过用“AS”还是不行)

【问题讨论】:

  • 在一行中有多个考试分数这一事实证明了数据设计存在缺陷。严格按照第三范式设计您的表格,您的问题将不复存在。

标签: sql oracle oracle-sqldeveloper


【解决方案1】:

为了清晰、测试和调试目的,您可以通过将相同的长表达式包含在子查询中来避免重复该表达式。例如:

select studentname,
  case when av >= 80 then 'EXCELLENT'
       when av >= 70 then 'VERY GOOD'
       when av >= 60 then 'GOOD'
       when av >= 50 then 'ACCEPTABLE'
       else 'FAIL'
  end as grade
from (
  SELECT s.studentname,
    (avg(cs.exam_season_one) + avg(cs.exam_season_two) + 
    avg(cs.degree_season_one) + avg(cs.degree_season_two)) / 4 as av
  FROM courses_student cs
  JOIN students c on s.student_id = cs.student_id
  GROUP BY s.studentname
) x

它看起来并不短,但发现错误并修复它要容易得多。

【讨论】:

    【解决方案2】:

    您可以像这样尝试 CTE:

    With CTE( 
    SELECT
        students.studentname, AVG(courses_student.exam_season_one) + AVG(courses_student.exam_season_two) + AVG(courses_student.degree_season_one) + AVG(courses_student.degree_season_two)) / 4 As average 
    FROM
        courses_student 
        JOIN
            students 
            ON students.student_id = courses_student.student_id 
    GROUP BY
        students.studentname
    )
    select
        studentname,
        case
            when
                average >= 80 
            then
                'EXCELLENT' 
            when
                average >= 70 
            then
                'VERY GOOD' 
            when
                average >= 60 
            then
                'GOOD' 
            when
                average >= 50 
            then
                'ACCEPTABLE' 
            else
                'FAIL' 
        end
        as grade 
    from
        CTE
    

    【讨论】:

      猜你喜欢
      • 2021-08-20
      • 2019-12-23
      • 1970-01-01
      • 1970-01-01
      • 2019-12-01
      • 2020-11-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多