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