简体   繁体   English

用于获取前3个rownum的子查询在pl / sql中不起作用

[英]subquery for getting top 3 rownum not work in pl/sql

DECLARE
    CURSOR EMPCUR 
      SELECT EMPNO,ENAME,SAL,ROWNUM 
        FROM (SELECT * 
                FROM EMP 
               ORDER BY SAL DESC) 
       WHERE ROWNUM<=3 
       ORDER BY ROWNUM;
BEGIN
  FOR EMPREC IN EMPCUR
  LOOP
    DBMS_OUTPUT.PUT_LINE('RANK '||EMPREC.ROWNUM);
    DBMS_OUTPUT.PUT_LINE(EMPREC.EMONO||' - '||EMPREC.ENAME||' - '||EMPREC.SAL);
  END LOOP;
END;
/

This code does not work: 此代码不起作用:

ERROR at line 2: ORA-06550: line 2, column 17: PLS-00103: Encountered the symbol "SELECT" when expecting one of the following: ( ; is return The symbol "is" was substituted for "SELECT" to continue. 第2行出现错误:ORA-06550:第2行,第17列:PLS-00103:在预期以下情况之一时遇到了符号“ SELECT”:(;返回return符号将“ is”替换为“ SELECT”以继续。

You have missed a IS on cursor declaration and there is a typo in line7 EMPREC.EMONO . 您错过了光标声明上的IS ,并且在第7行EMPREC.EMONO有一个错字。

Try like this, 这样尝试

DECLARE
    CURSOR EMPCUR IS  SELECT EMPNO,ENAME,SAL,ROWNUM FROM (SELECT * FROM EMP ORDER BY SAL DESC) WHERE ROWNUM<=3 ORDER BY ROWNUM;
BEGIN
    FOR EMPREC IN EMPCUR
    LOOP
        DBMS_OUTPUT.PUT_LINE('RANK '||EMPREC.ROWNUM);
        DBMS_OUTPUT.PUT_LINE(EMPREC.EMPNO||' - '||EMPREC.ENAME||' - '||EMPREC.SAL);
    END LOOP;
END;
/

I would like to suggest that ranking things using the rownum pseudocolumn in a subquery is at best a flawed approach, rarely delivering on the actual goal. 我想建议在子查询中使用rownum伪列对事物进行排名充其量是一种有缺陷的方法,很少实现实际目标。 For instance, do you want the employees with the top three salaries? 例如,您想让员工获得前三名的薪水吗? Or do you always want up to three records? 还是您总是想要最多三个记录? How does this equation cope with employees with identical salaries? 这个等式如何应付薪水相同的员工? Et cetera. 等等。

It is a better approach to use the analytic functions, define your explicit rankings in those functions and return the results that actually answer the question. 这是使用分析函数,在这些函数中定义显式排名并返回实际回答问题的结果的更好方法。

begin
    for rec in ( select sq.*
                   from ( select e.employee_id
                               , e.first_name ||' '|| e.last_name as full_name 
                               , e.salary
                               , rank() over (order by e.salary desc) as salary_rank
                            from hr.employees e ) sq
                  where sq.salary_rank <= 3
                  order by sq.salary desc )
    loop
        dbms_output.put_line('RANK ' || rec.salary_rank);
        dbms_output.put_line(rec.employee_id || ' - ' || rec.full_name || ' - ' || rec.salary);
    end loop;
end;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM