2

期末試験で最高点を取った生徒を獲得しようとしています

最初に私が選ぶ

SELECT s.STUDENT_ID, w.LAST_NAME,w.FIRST_NAME, MAX(s.NUMERIC_GRADE) AS NUMERIC_FINAL_GRADE
FROM GRADE s , SECTION z, STUDENT w
WHERE s.SECTION_ID = z.SECTION_ID AND s.STUDENT_ID = w.STUDENT_ID
AND z.COURSE_NO = 230 AND z.SECTION_ID = 100 AND s.GRADE_TYPE_CODE = 'FI'
GROUP BY s.STUDENT_ID, w.FIRST_NAME,w.LAST_NAME

それは私にこの結果を与え、それが私が望むものです

 STUDENT_ID LAST_NAME                 FIRST_NAME                NUMERIC_FINAL_GRADE
  ---------- ------------------------- ------------------------- -------------------
   262 Walston                   Donna                                      85 
   141 Boyd                      Robert                                     84 

しかし、これら2つから最大値を取得しようとすると、行が表示されないか、エラーが発生します

i.STUDENT_ID, k.LAST_NAME,k.FIRST_NAME
FROM GRADE i , SECTION j, STUDENT k
WHERE i.SECTION_ID = j.SECTION_ID AND i.STUDENT_ID = k.STUDENT_ID
AND j.COURSE_NO = 230 AND j.SECTION_ID = 100 AND i.GRADE_TYPE_CODE = 'FI' 
GROUP BY i.STUDENT_ID, k.FIRST_NAME,k.LAST_NAME
HAVING COUNT(*) =
(SELECT MAX(NUMERIC_FINAL_GRADE)
 FROM
(SELECT s.STUDENT_ID, w.LAST_NAME,w.FIRST_NAME, MAX(s.NUMERIC_GRADE) AS NUMERIC_FINAL_GRADE
FROM GRADE s , SECTION z, STUDENT w
WHERE s.SECTION_ID = z.SECTION_ID AND s.STUDENT_ID = w.STUDENT_ID
AND z.COURSE_NO = 230 AND z.SECTION_ID = 100 AND s.GRADE_TYPE_CODE = 'FI'
GROUP BY s.STUDENT_ID, w.FIRST_NAME,w.LAST_NAME))

ORDER BY i.STUDENT_ID, k.LAST_NAME,k.FIRST_NAME;

すでに持っているこれらの 2 つの結果から最大の結果を得るにはどうすればよいですか? また、行が表示されない、またはエラーが発生するのはなぜですか?

4

2 に答える 2

4

従来の方法は分析 MAX()(または他の分析関数) です。

select *
  from ( select s.student_id
              , w.last_name
              , w.first_name
              , s.numeric_grade
              , max(s.numeric_grade) over () as numeric_final_grade
           from grade s
           join section z
             on s.section_id = z.section_id
           join student w
             on s.student_id = w.student_id
          where z.course_no = 230 
            and z.section_id = 100 
            and s.grade_type_code = 'FI'
                )
 where numeric_grade = numeric_final_grade

しかし、おそらくFIRST (KEEP) を使用することをお勧めします。

select max(s.student_id) keep (dense_rank first order by s.numeric_grade desc) as student_id
     , max(w.last_name) keep (dense_rank first order by s.numeric_grade desc) as last_name
     , max(w.first_name) keep (dense_rank first order by s.numeric_grade desc) as first_na,e
     , max(s.numeric_grade_name) as numeric_final_grade
  from grade s
  join section z
    on s.section_id = z.section_id
  join student w
    on s.student_id = w.student_id
 where z.course_no = 230 
   and z.section_id = 100 
   and s.grade_type_code = 'FI'

最初に提案したものに対するこれらの両方のアプローチの利点は、テーブルを1回スキャンするだけで、テーブルまたはインデックスに2回アクセスする必要がないことです。この 2 つの違いについては、Rob van Wijk のブログ投稿を強くお勧めします。

PSこれらは異なる結果を返すため、わずかに異なります。分析関数は、2 人の学生が同じ最大スコアを持つ重複を維持します (これは、あなたの提案も同様です)。集計関数は重複を削除し、同点の場合はランダム レコードを返します。

于 2013-10-17T19:37:30.400 に答える
1
SELECT * FROM 
(
  SELECT s.STUDENT_ID, w.LAST_NAME,w.FIRST_NAME, 
     MAX(s.NUMERIC_GRADE) AS NUMERIC_FINAL_GRADE
  FROM GRADE s, SECTION z, STUDENT w
  WHERE s.SECTION_ID = z.SECTION_ID 
     AND s.STUDENT_ID = w.STUDENT_ID
     AND z.COURSE_NO = 230 AND z.SECTION_ID = 100 
     AND s.GRADE_TYPE_CODE = 'FI'
  GROUP BY s.STUDENT_ID, w.FIRST_NAME, w.LAST_NAME
  ORDER BY MAX(s.NUMERIC_GRADE)
) AS M 
WHERE ROWNUM <= 1
于 2013-10-17T19:36:10.537 に答える