隨筆-314  評論-209  文章-0  trackbacks-0

          轉自:http://blog.csdn.net/wh62592855/article/details/4988336
          例如說吧,對DEPTNO 10中的每個員工,確定聘用他們的日期及聘用下一個員工(可能是其他部門的員工)的日期之間相差的天數。

          SQL> select ename,hiredate,deptno from emp order by hiredate;

          ENAME      HIREDATE            DEPTNO
          ---------- --------------- ----------
          SMITH      17-DEC-80               20
          ALLEN      20-FEB-81               30
          WARD       22-FEB-81               30
          JONES      02-APR-81               20
          BLAKE      01-MAY-81               30
          CLARK      09-JUN-81               10
          TURNER     08-SEP-81               30
          MARTIN     28-SEP-81               30
          KING       17-NOV-81               10
          JAMES      03-DEC-81               30
          FORD       03-DEC-81               20

          ENAME      HIREDATE            DEPTNO
          ---------- --------------- ----------
          MILLER     23-JAN-82               10
          SCOTT      19-APR-87               20
          ADAMS      23-MAY-87               20

          14 rows selected.

           

          SQL> select ename,hiredate,next_hd,
            2  next_hd-hiredate diff
            3  from
            4  (
            5  select deptno,ename,hiredate,
            6  lead(hiredate) over(order by hiredate) next_hd
            7  from emp
            8  )
            9  where deptno=10;

          ENAME      HIREDATE        NEXT_HD               DIFF
          ---------- --------------- --------------- ----------
          CLARK      09-JUN-81       08-SEP-81               91
          KING       17-NOV-81       03-DEC-81               16
          MILLER     23-JAN-82       19-APR-87             1912

          這里的LEAD OVER非常有用,它能夠訪問“未來的”行(“未來的”行相對于當前行,由ORDER BY子句決定)。這種無需添加聯接就能夠訪問當前行附近行的功能,提高了代碼的可讀性和有效性。在采用窗口函數時,一定要記住,它在WHERE子句之后求值,因此在該解決方案中,需要使用內聯視圖。如果把對DEPTNO的篩選移到內聯視圖,則結果會發生改變(僅考慮了DETPNO 10中的HIREDATE)。

          所以下面的結果是錯誤的:

          SQL> select ename,hiredate,next_hd,
            2  next_hd-hiredate diff
            3  from
            4  (
            5  select deptno,ename,hiredate,
            6  lead(hiredate) over(order by hiredate) next_hd
            7  from emp
            8  where deptno=10
            9  );

          ENAME      HIREDATE        NEXT_HD               DIFF
          ---------- --------------- --------------- ----------
          CLARK      09-JUN-81       17-NOV-81              161
          KING       17-NOV-81       23-JAN-82               67
          MILLER     23-JAN-82

           

          對于ORACLE的LEAD和LAG函數還需要特別注意,它們的結果中可能會有重復。在上面的例子中表EMP內不包含重復的HIREDATE,所以“看起來”似乎沒有什么問題。下面我們向表中插入4個重復值來看看

          SQL> insert into emp(empno,ename,deptno,hiredate)
            2  values(1,'a',10,to_date('17-NOV-1981'));

          1 row created.

          SQL> insert into emp(empno,ename,deptno,hiredate)
            2  values(2,'b',10,to_date('17-NOV-1981'));

          1 row created.

          SQL> insert into emp(empno,ename,deptno,hiredate)
            2  values(3,'c',10,to_date('17-NOV-1981'));

          1 row created.

          SQL> insert into emp(empno,ename,deptno,hiredate)
            2  values(4,'d',10,to_date('17-NOV-1981'));

          1 row created.

          SQL> select ename,hiredate
            2  from emp
            3  where deptno=10
            4  order by 2;

          ENAME      HIREDATE
          ---------- ---------------
          CLARK      09-JUN-81
          b          17-NOV-81
          c          17-NOV-81
          a          17-NOV-81
          d          17-NOV-81
          KING       17-NOV-81
          MILLER     23-JAN-82

          7 rows selected.

          現在還是用以前那個查詢語句來試試

          SQL> select ename,hiredate,next_hd,
            2  next_hd-hiredate diff
            3  from
            4  (
            5  select deptno,ename,hiredate,
            6  lead(hiredate) over(order by hiredate) next_hd
            7  from emp
            8  )
            9  where deptno=10;

          ENAME      HIREDATE        NEXT_HD               DIFF
          ---------- --------------- --------------- ----------
          CLARK      09-JUN-81       08-SEP-81               91
          d          17-NOV-81       17-NOV-81                0
          c          17-NOV-81       17-NOV-81                0
          a          17-NOV-81       17-NOV-81                0
          b          17-NOV-81       17-NOV-81                0
          KING       17-NOV-81       03-DEC-81               16
          MILLER     23-JAN-82       19-APR-87             1912

          7 rows selected.

          可以看到其中有4個員工的DIFF列值都是0,這是錯誤的,同一天聘用的所有員工都應該跟下一個聘用其他員工的HIREDATE進行計算。

          幸運的是ORACLE針對這類情況提供了一個非常簡單的措施:當調用LEAD函數時,可以給LEAD傳遞一個參數,以便準確的指定“未來的”行(是下一行?10行之后?等等)。

          select ename,hiredate,next_hd,
          next_hd-hiredate diff
          from
          (
          select deptno,ename,hiredate,
          lead(hiredate,cnt-rn+1) over(order by hiredate) next_hd
          from
          (
          select deptno,ename,hiredate,
          count(*) over(partition by hiredate) cnt,
          row_number() over(partition by hiredate order by empno) rn
          from emp
          where deptno=10
          )
          )

           

          posted on 2011-12-09 10:40 xzc 閱讀(4201) 評論(1)  編輯  收藏 所屬分類: Oracle

          評論:
          # re: ORACLE確定當前記錄和下一條記錄之間的差值 2012-07-12 11:19 | xzc
          SQL> select replace(wm_concat(menu_name), ',', '->')
          2 from (select level, a.*
          3 from mm_menu a
          4 start with menu_id = 1021057
          5 connect by menu_id = prior super_id
          6 order by level desc);

          REPLACE(WM_CONCAT(MENU_NAME),'
          --------------------------------------------------------------------------------
          系統菜單->系統管理->數據質量->業務發展(分公司)->WIFI場景建設效益監控報表  回復  更多評論
            
          主站蜘蛛池模板: 从化市| 沧州市| 宝丰县| 苍南县| 东阿县| 阜新市| 河池市| 黄陵县| 明光市| 太和县| 宣城市| 金湖县| 紫金县| 隆回县| 开远市| 阿合奇县| 灵石县| 海晏县| 香格里拉县| 花莲县| 南华县| 曲靖市| 霍邱县| 祁连县| 孝昌县| 德惠市| 精河县| 津市市| 平乡县| 新兴县| 伽师县| 大悟县| 牟定县| 正定县| 沂水县| 南岸区| 台南市| 化隆| 灵寿县| 朔州市| 阳城县|