从与另一个列的最大值关联的列中返回值

时间:2018-09-19 15:28:25

标签: sql oracle plsql

对不起,标题令人困惑,但我不知道该怎么表达我的问题。

我有一个查询,该查询返回一张测验分数表以及测验本身的一些描述:

+----------------+------------+-----------+ | student_id | test_score | test_term | +----------------+------------+-----------+ | 1 123 | 614 | Spring | | 2 123 | 547 | Summer | | 3 123 | 628 | Fall | +----------------+------------+-----------+

如您所见,学生123参加了3次数学测试。我正在尝试编写一个查询,该查询将返回Student 123达到的最高分数以及与该分数相关的测试词。这是我到目前为止的内容:

SELECT
   MAX (test_score) as "highest_math_score",
   CASE WHEN test_score = MAX(test_score) THEN test_term 
        ELSE null 
   END as "highest_test_term"
FROM Table1
GROUP BY
   student_id

但是,我遇到了错误:not a GROUP BY expression.

关于如何执行此操作的任何想法?

3 个答案:

答案 0 :(得分:2)

您可以使用MAX..KEEP

SELECT student_id, 
       max(test_score), 
       max(test_term) KEEP ( DENSE_RANK FIRST ORDER BY test_score desc )
FROM test_data
GROUP BY student_id;

完整示例:

WITH test_data ( student_id, test_score, test_term ) AS
( SELECT 123, 614, 'Spring' FROM DUAL UNION ALL
 SELECT 123, 547, 'Summer' FROM DUAL UNION ALL
 SELECT 123, 628, 'Fall' FROM DUAL UNION ALL
 SELECT 456, 999, 'Spring' FROM DUAL UNION ALL
 SELECT 456, 1111, 'Summer' FROM DUAL UNION ALL
 SELECT 456, 888, 'Fall' FROM DUAL )
SELECT student_id, max(test_score), max(test_term) KEEP ( DENSE_RANK FIRST ORDER BY test_score desc )
FROM test_data
GROUP BY student_id;
+------------+-----------------+--------+
| STUDENT_ID | MAX(TEST_SCORE) |  TERM  |
+------------+-----------------+--------+
|        123 |             628 | Fall   |
|        456 |            1111 | Summer |
+------------+-----------------+--------+

答案 1 :(得分:1)

您似乎想要:

SELECT MAX(test_score) OVER (PARTITION BY student_id) AS "highest_math_score",
       (CASE WHEN test_score = MAX(test_score) OVER (PARTITION BY student_id) 
             THEN test_term 
        END) AS "highest_test_term"
FROM Table1;

但是,您也可以使用dense_rank()

SELECT t1.*
FROM (SELECT t.*, DENSE_RANK() OVER (PARTITION BY student_id ORDER BY test_score DESC) AS seq
      FROM Table1 t
     ) t1
WHERE seq = 1;

另一个选项是具有相关性方法的子查询:

SELECT t.*
FROM Table1 t
WHERE test_score = (SELECT MAX(t1.test_score) FROM Table1 t1 WHERE t1.student_id = t.student_id);

答案 2 :(得分:1)

没有任何窗口功能:

select t1.student_id, t."highest_math_score"
  from t1 
  join  
(SELECT
   MAX (test_score) as "highest_math_score", student_id
FROM t1
GROUP BY
   student_id)t on t.student_id = t1.student_id and t.highest_math_score = t1.test_score