2012-07-24 66 views
0
Student Subj Period Score 
------------------------- 
A   Math 100  50 
A   Hist 100  100 
A   Sci 200  70 
B   Math 100  50 
B   Hist 100  50 

我试图查询每个学生的最高分数。plsql比较并获得最大值

如果分数都相同(如“B”然后挑一个在底部。如果这是不可能的,只是挑不出什么

我使用MAX()和最小不好受()和GROUP BY以获得正确的结果 结果应该是这样的

Student Subj Period Score 
------------------------- 
A   Hist 100  100 
B   Hist 100  50 
+1

什么是“底部”?表中没有任何自然顺序 – zerkms 2012-07-24 23:26:11

+0

其实我的意图是......如果结果已经有'历史',那么可以选择'数学'而不是'历史'来得到下一个结果。但是,这似乎不可能在一个查询 – sayhaha 2012-07-24 23:28:28

回答

2

你想使用分析功能(我认为这是Oracle的PL/SQL的提):

select Student, Subj, Period, Score 
from (select t.*, 
      row_number() over (partition by student order by score desc) as seqnum 
     from t 
    ) t 
where seqnum = 1 
+0

gee ....... nius! – sayhaha 2012-07-24 23:47:03

+0

我知道OP没有请求这个,但查询不是确定的。可以通过简单地添加句点并受到ORDER BY子句的限制来确定它。 – dbenham 2012-07-25 10:04:43

1

戈登的答案肯定奏效,并且它使用ANSI语法,该语法由许多数据库引擎支持。

Oracle有一个额外的语法,我不认为是ANSI,但它消除了对任何子查询的需要。它的表现至少和戈登的回答一样好(可能稍微快一点,但我不确定)。它使用KEEP LAST扩展来聚合函数。

select student, 
     max(subj) keep(dense_rank last order by score, period) as subj, 
     max(period) keep(dense_rank last order by score, period) as period, 
     max(score) as score 
    from grades 
group by student 
; 

注 - 除非你明确要提供随机的结果,你应该始终构建您的查询给定的答案,也就是说,一组给定的数据总是会给出相同的答案,不管数据是如何加载。我将上述查询按最高分排序,然后是最高分。如果还有一条平行线,则返回max(subj)。