Oracle_SQL常见问题(TOPM~N)_02


求M-N问题

1.  rownum伪列

对rownum进行提前的判断,缩小了检索的范围

SELECT  t2.*
FROM   (SELECTrownum lvl, t1.*
        FROM  (SELECT emp.empno, ename, nvl(sal, 0)
                FROM   emp
                ORDER  BY nvl(sal, 0) DESC) t1
        WHERE rownum <= 4) t2
WHERE  t2.lvl >= 2

2.  rownum伪列

SELECT t2.*
FROM   (SELECTrownum lvl, t1.*
        FROM  (SELECT emp.empno, ename,sal
                FROM   emp
                ORDER  BY nvl(sal, 0) DESC) t1) t2
WHERE  t2.lvl BETWEEN 2 AND 4

3.minus

SELECTrownum, t1.*
FROM   (SELECT * FROM emp ORDERBY nvl(sal, 0) DESC) t1
WHERE  rownum <= 4
MINUS
SELECTrownum, t1.*
FROM   (SELECT * FROM emp ORDERBY nvl(sal, 0) DESC) t1
WHERE  rownum = 1

当然我们可以利用集合的差运算,注意,rownum不能用于等于,用于等于的时候只能有一种情况

那就是当rownum = 1的时候

4利用oracle自带的函数来进行求解

row_number() over( ) 按照行的序号来显示

SELECT t2.*
FROM   (SELECT t1.empno,
               t1.ename,
               t1.sal,
               row_number() over(ORDER BY t1.sal DESC) grade
        FROM  emp t1) t2
WHERE  t2.grade BETWEEN 2 AND 4


dense_rank( ) over( )   

SELECT t2.*
FROM   (SELECT t1.empno,
               t1.ename,
               t1.sal,
               dense_rank() over(ORDER BY t1.sal DESC) grade
        FROM  emp t1) t2
WHERE  t2.grade BETWEEN 2 AND 4


rank( )over( )   

SELECT t2.*
FROM   (SELECT t1.deptno,
               t1.empno,
               t1.ename,
               t1.sal,
               rank() over(ORDER BY t1.sal DESC) grade
        FROM  emp t1) t2
WHERE  t2.grade BETWEEN 2 AND 4


根据需要来选择函数

Q:求各个部门的工资在2-4名的员工。(PARTITION BY)

SELECT t2.*
FROM   (SELECT t1.deptno,
               t1.empno,
               t1.ename,
               t1.sal,
               rank() over(PARTITION BY deptno ORDER BY t1.sal DESC) grade
        FROM  emp t1) t2
WHERE  t2.grade BETWEEN 2 AND 4



注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2020 ITdaan.com