我正在尝试在这里使用SQL语句并将其放入游标中。不幸的是,我无法对此特定任务使用Rank()函数。
CREATE or REPLACE PROCEDURE RankGPA
IS
vSnum student.snum%type;
vSname student.sname%type;
vGPA student.GPA%type;
vMajor student.major%type;
CURSOR rankGPA_cursor IS
SELECT s1.snum, s1.sname, s1.gpa, count( s2.gpa ) + 1 as rank, s1.major
FROM students s1
LEFT JOIN students s2
ON s1.GPA < s2.GPA
GROUP BY s1.snum, s1.sname, s1.gpa, s1.Major
ORDER BY 4;
BEGIN
OPEN rankGPA_cursor;
FETCH rankGPA_cursor INTO vSnum, vSname, vGPA, vMajor;
END;
我正在尝试获得这样的输出:
Rank SNUM SNAME GPA MAJOR
**** **** ***** *** *****
1 101 Bob 4 ENGR
2 102 Cari 3.5 ENGL
答案 0 :(得分:1)
我已经为emp表执行了类似的操作。您可以为学生表更改它:
1.没有排名超过功能:
SELECT x.ranking,ename,sal
FROM emp e,
(
SELECT e2.empno, COUNT(*) AS
ranking
FROM emp e1,emp e2 WHERE e1.sal<=e2.sal
GROUP BY e2.empno
)x
WHERE e.empno=x.empno
ORDER BY sal
2.排名超过功能:
SELECT RANK () OVER (ORDER BY sal DESC ) AS ranking ,empno,ename,sal
FROM emp
注意:如果有联系,您可以使用DENSE_RANK
SELECT DENSE_RANK () OVER (ORDER BY sal DESC ) AS ranking ,empno,ename,sal
FROM emp
答案 1 :(得分:1)
评论中的措词有点令人困惑,但听起来他们希望你有一个局部变量来充当排名&#39;通过计算获取的行数,例如:
DECLARE
counter pls_integer := 0;
CURSOR rankGPA_cursor IS
SELECT s.snum, s.sname, s.gpa, s.major
FROM students s
ORDER BY s.gpa DESC;
BEGIN
FOR rankGPA_row IN rankGPA_cursor LOOP
counter := counter + 1;
dbms_output.put_line(counter
||' '|| rankGPA_row.snum
||' '|| rankGPA_row.sname
||' '|| rankGPA_row.gpa
||' '|| rankGPA_row.major
);
END LOOP;
END;
/
每次循环counter
变量都会增加。由于游标查询按GPA 降序排序,因此第一行提取的GPA最高,此时计数器为1。
使用dbms_output
这是不好的做法,因为在现实世界中,您不知道客户端是否已启用,并且您必须做一些工作来整齐地格式化打印结果。但无论如何这都是人为的。
如果两名学生具有相同的GPA,您还需要考虑如何对事物进行排名。目前,这将对学生进行任意排名。您可以更改order by
子句以添加(例如)按名称进行二级排序;但是得分相关的学生仍会获得不同的排名。即使使用这种方法,通过跟踪最后看到的GPA并且如果新行的值与前一个值不同,仅增加秩/计数器,当然可以给予它们相同的等级。我不知道你预计会产生什么。
你可以使用任何风格的光标;显式或隐式,并且如果您愿意,可以使用cursor-for-loop或在循环关闭中使用显式open-fetch。
答案 2 :(得分:0)
您可以考虑使用windowed functions
:
SELECT s1.snum, s1.sname, s1.gpa, s1.Major,RANK() OVER(ORDER BY s1.gpa) AS r
FROM students s1;
来自RANK doc:
RANK计算一组值中值的等级。返回类型为NUMBER。