我已经计算出每所学校的学生获得的最高GPA。但是,如何获得每所学校的学生为RANK 1, 2, and 3
得分最高的3个GPA列表?
SELECT A.*
FROM (
SELECT B.SCHOOL_NAME
,C.STUDENT_NAME
,A.SYMBOL_NO
,A.AVG_GPA
,MAX(A.AVG_GPA) OVER (PARTITION BY B.SCHOOL_NAME) AS MAX_GPA
FROM TBL_STUDENT_MARKS A
INNER JOIN TBL_SCHOOL B ON A.SCHOOL_ID = B.SCHOOL_ID
INNER JOIN TBL_STUDENT_INFO C ON A.SYMBOL_NO = C.SYMBOL_NO
AND B.SCHOOL_ID = C.SCHOOL_ID
) A
WHERE A.AVG_GPA = MAX_GPA
ORDER BY A.AVG_GPA DESC;
答案 0 :(得分:1)
您可以结合使用DENSE_RANK()
和PARTITION BY
:
DENSE_RANK() OVER (
PARTITION BY <expr1>[{,<expr2>...}]
ORDER BY <expr1> [ASC|DESC], [{,<expr2>...}]
)
在这种情况下,类似
DENSE_RANK() OVER (PARTITION BY B.SCHOOL_NAME ORDER BY AVG_GPA desc) AS SCHOOL_RANK
,然后在外部查询中添加
WHERE SCHOOL_RANK in (1, 2, 3)
也
查看常用表表达式!我发现它通常比嵌套SELECT
更好。
WITH ranked as (
SELECT
SCHOOL_ID
, SYMBOL_NO
, AVG_GPA
, DENSE_RANK() OVER (PARTITION BY SCHOOL_ID ORDER BY AVG_GPA DESC) AS SCHOOL_RANK
FROM TBL_STUDENT_MARKS
)
SELECT
SC.SCHOOL_NAME
, INFO.STUDENT_NAME
, ST.SYMBOL_NO
, ST.AVG_GPA
, ST.SCHOOL_RANK
FROM ranked ST
INNER JOIN TBL_SCHOOL SC ON R.SCHOOL_ID = SC.SCHOOL_ID
INNER JOIN TBL_STUDENT_INFO INFO ON ST.SYMBOL_NO = INFO.SYMBOL_NO AND SC.SCHOOL_ID = INFO.SCHOOL_ID
WHERE SCHOOL_RANK <= 3
ORDER BY SCHOOL_NAME, SCHOOL_RANK;
答案 1 :(得分:1)
您可以使用RANK()或DENSE_RANK()或ROW_NUMBER()来获得结果。 但是,在这种情况下,最好使用RANK()和DENSE_RANK()。
RANK():
SELECT A.*
FROM (
SELECT B.SCHOOL_NAME
,C.STUDENT_NAME
,A.SYMBOL_NO
,A.AVG_GPA
,RANK() OVER (PARTITION BY B.SCHOOL_NAME ORDER BY A.AVG_GPA DESC) AS SCHOOL_RANK
FROM TBL_STUDENT_MARKS A
INNER JOIN TBL_SCHOOL B ON A.SCHOOL_ID = B.SCHOOL_ID
INNER JOIN TBL_STUDENT_INFO C ON A.SYMBOL_NO = C.SYMBOL_NO AND B.SCHOOL_ID = C.SCHOOL_ID
) A
WHERE SCHOOL_RANK <= 3
ORDER BY SCHOOL_NAME, SCHOOL_RANK
DENSE_RANK():
SELECT A.*
FROM (
SELECT B.SCHOOL_NAME
,C.STUDENT_NAME
,A.SYMBOL_NO
,A.AVG_GPA
,DENSE_RANK() OVER (PARTITION BY B.SCHOOL_NAME ORDER BY A.AVG_GPA DESC) AS SCHOOL_DENSE_RANK
FROM TBL_STUDENT_MARKS A
INNER JOIN TBL_SCHOOL B ON A.SCHOOL_ID = B.SCHOOL_ID
INNER JOIN TBL_STUDENT_INFO C ON A.SYMBOL_NO = C.SYMBOL_NO AND B.SCHOOL_ID = C.SCHOOL_ID
) A
WHERE SCHOOL_DENSE_RANK<= 3
ORDER BY SCHOOL_NAME, SCHOOL_DENSE_RANK
ROW_NUMBER():
SELECT A.*
FROM (
SELECT B.SCHOOL_NAME
,C.STUDENT_NAME
,A.SYMBOL_NO
,A.AVG_GPA
,ROW_NUMBER() OVER (PARTITION BY B.SCHOOL_NAME ORDER BY A.AVG_GPA DESC) AS SCHOOL_ROW_NUMBER
FROM TBL_STUDENT_MARKS A
INNER JOIN TBL_SCHOOL B ON A.SCHOOL_ID = B.SCHOOL_ID
INNER JOIN TBL_STUDENT_INFO C ON A.SYMBOL_NO = C.SYMBOL_NO AND B.SCHOOL_ID = C.SCHOOL_ID
) A
WHERE SCHOOL_ROW_NUMBER <= 3
ORDER BY SCHOOL_NAME, SCHOOL_ROW_NUMBER
有关排名,DenseRank和行号之间的区别,请参考here
答案 2 :(得分:0)
将MAX()
窗口函数替换为DENSE_RANK()
:
SELECT A.*
FROM (
SELECT B.SCHOOL_NAME
, C.STUDENT_NAME
, A.SYMBOL_NO
, A.AVG_GPA
, DENSE_RANK() OVER (PARTITION BY B.SCHOOL_NAME ORDER BY A.AVG_GPA DESC) AS RANK_BY_SCHOOL
FROM TBL_STUDENT_MARKS A
INNER JOIN TBL_SCHOOL B ON A.SCHOOL_ID = B.SCHOOL_ID
INNER JOIN TBL_STUDENT_INFO C ON A.SYMBOL_NO = C.SYMBOL_NO AND B.SCHOOL_ID = C.SCHOOL_ID
) A
WHERE RANK_BY_SCHOOL <= 3
ORDER BY SCHOOL_NAME, RANK_BY_SCHOOL;
答案 3 :(得分:0)
您可以使用ROW_NUMBER() OVER (PARTITION BY B.SCHOOL_NAME ORDER BY A.AVG_GPA DESC)
SELECT A.*
FROM (
SELECT B.SCHOOL_NAME
,C.STUDENT_NAME
,A.SYMBOL_NO
,A.AVG_GPA
,ROW_NUMBER() OVER (PARTITION BY B.SCHOOL_NAME ORDER BY A.AVG_GPA DESC)
AS HIGHEST_GPA
FROM TBL_STUDENT_MARKS A
INNER JOIN TBL_SCHOOL B ON A.SCHOOL_ID = B.SCHOOL_ID
INNER JOIN TBL_STUDENT_INFO C ON A.SYMBOL_NO = C.SYMBOL_NO
AND B.SCHOOL_ID = C.SCHOOL_ID
) A
WHERE HIGHEST_GPA <= 3
ORDER BY A.AVG_GPA DESC;
答案 4 :(得分:0)
使用Dense_rank窗口功能:
select *
from(SELECT A.*,DENSE_RANK()over(partition by school_name order by MAX_GPA
desc)as rankno
FROM (
SELECT B.SCHOOL_NAME
,C.STUDENT_NAME
,A.SYMBOL_NO
,A.AVG_GPA
,MAX(A.AVG_GPA) OVER (PARTITION BY B.SCHOOL_NAME) AS MAX_GPA
FROM TBL_STUDENT_MARKS A
INNER JOIN TBL_SCHOOL B ON A.SCHOOL_ID = B.SCHOOL_ID
INNER JOIN TBL_STUDENT_INFO C ON A.SYMBOL_NO = C.SYMBOL_NO
AND B.SCHOOL_ID = C.SCHOOL_ID
) A
A.AVG_GPA = MAX_GPA)B WHERE Rankno IN(1,2,3);