使用游标进行排序的PL/SQL程序

使用游标进行排序的PL/SQL程序,sql,oracle,plsql,cursor,oracle10g,Sql,Oracle,Plsql,Cursor,Oracle10g,我试图在这里使用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,

我试图在这里使用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;

可以考虑使用<代码>窗口函数< /> >:

SELECT s1.snum, s1.sname, s1.gpa, s1.Major,RANK() OVER(ORDER BY s1.gpa) AS r
FROM students s1;
发件人:

秩计算一组值中某个值的秩。返回类型为数字


可以考虑使用<代码>窗口函数< /> >:

SELECT s1.snum, s1.sname, s1.gpa, s1.Major,RANK() OVER(ORDER BY s1.gpa) AS r
FROM students s1;
发件人:

秩计算一组值中某个值的秩。返回类型为数字


我对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
SELECT  RANK () OVER (ORDER BY  sal DESC ) AS ranking ,empno,ename,sal

FROM emp
注意:如果有联系,您可以使用密集排列

SELECT  DENSE_RANK () OVER (ORDER BY  sal DESC ) AS ranking ,empno,ename,sal

FROM emp

我对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
SELECT  RANK () OVER (ORDER BY  sal DESC ) AS ranking ,empno,ename,sal

FROM emp
注意:如果有联系,您可以使用密集排列

SELECT  DENSE_RANK () OVER (ORDER BY  sal DESC ) AS ranking ,empno,ename,sal

FROM emp

您的评论中的措辞有点混乱,但听起来他们希望您在获取行时通过计算行数来使用局部变量作为“秩”,例如:

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;
/
每次循环时,
计数器
变量都会增加。因为游标查询是按GPA降序排序的,所以获取的第一行具有最高的GPA,此时计数器为1

使用
dbms\u输出
是一种糟糕的做法,因为在现实世界中,您不知道客户机是否启用了该功能,并且您必须做一些工作来整齐地格式化打印的结果。但无论如何,这都是人为的

如果两个学生有相同的GPA,那么你也需要考虑如何排序。目前,这将随意对并列学生进行排名。您可以将
orderby
子句更改为添加,例如,按名称进行二次排序;但成绩平平的学生仍然会得到不同的排名。当然,即使使用这种方法,也可以给他们相同的排名,方法是跟踪最后一次看到的GPA,如果新行的值与前一行的值不同,则只增加排名/计数器。不过我不知道你要做什么


您可以为此使用任何样式的光标;显式或隐式,如果您愿意,可以使用循环游标或循环闭合中的显式打开获取。

注释中的措辞有点混乱,但听起来他们希望您在获取行时通过计算行数来使用局部变量作为“秩”,例如:

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;
/
每次循环时,
计数器
变量都会增加。因为游标查询是按GPA降序排序的,所以获取的第一行具有最高的GPA,此时计数器为1

使用
dbms\u输出
是一种糟糕的做法,因为在现实世界中,您不知道客户机是否启用了该功能,并且您必须做一些工作来整齐地格式化打印的结果。但无论如何,这都是人为的

如果两个学生有相同的GPA,那么你也需要考虑如何排序。目前,这将随意对并列学生进行排名。您可以将
orderby
子句更改为添加,例如,按名称进行二次排序;但成绩平平的学生仍然会得到不同的排名。当然,即使使用这种方法,也可以给他们相同的排名,方法是跟踪最后一次看到的GPA,如果新行的值与前一行的值不同,则只增加排名/计数器。不过我不知道你要做什么


您可以为此使用任何样式的光标;显式或隐式,如果您愿意,可以使用游标进行循环,也可以使用显式打开获取进行循环关闭。

您有两个相同的别名用于students表(左连接students s2)。谢谢,我编辑了它!您只从游标中获取一行,并且没有对其执行任何操作。输出应该去哪里?为什么要使用PL/SQL?为什么您不能使用
rank()
——您被告知不要使用,或者您不知道如何使用?其他分析函数呢?我想我应该做一个dbms_输出。获取这些值。我被告知不要使用rank()或任何其他函数。我们得到的提示是使用fetch为秩编号添加一个计数器。一旦fetch达到最高GPA,它将打印排名和其他。您有两个相同的学生别名表(左加入学生s2)谢谢,我编辑了它!您只从游标中获取一行,并且没有对其执行任何操作。输出应该去哪里?为什么要使用PL/SQL?为什么您不能使用
rank()
——您被告知不要使用,或者您不知道如何使用?其他分析函数呢?我想我应该做一个dbms_输出。获取这些值。我被告知不要使用rank()或任何其他函数。我们得到的提示是使用fetch为秩编号添加一个计数器。一旦fetch达到最高GPA,它就会打印排名以及其他。这一点解释得很好。谢谢你抽出时间,我从中学到了很多!这解释得很好。谢谢你抽出时间,我从中学到了很多!