<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    紙飛機(jī)

      BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
      22 隨筆 :: 28 文章 :: 30 評(píng)論 :: 0 Trackbacks

    問題:計(jì)算某個(gè)列中所有值的累計(jì)和

    解決方案

    下面給出了一種解決方案,它展示了如何計(jì)算所有職員工資的累計(jì)和。為增加可讀性,其結(jié)果是按SAL排序的,這樣就能夠很容易地觀察到累計(jì)和變化的過程。

    DB2和Oracle

    使用窗口版本的SUM函數(shù)計(jì)算累計(jì)和:

    1 select ename, sal,

    2         sum(sal) over (order by sal,empno) as running_total

    3    from emp

    4    order by 2

    ENAME              SAL RUNNING_TOTAL

    ---------- ---------- -------------

    SMITH              800            800

    JAMES              950           1750

    ADAMS             1100           2850

    WARD              1250           4100

    MARTIN            1250           5350

    MILLER            1300           6650

    TURNER            1500           8150

    ALLEN             1600           9750

    CLARK             2450          12200

    BLAKE             2850          15050

    JONES             2975          18025

    SCOTT             3000          21025

    FORD              3000          24025

    KING              5000          29025

    MySQL、PostgreSQL和SQL Server

    使用標(biāo)量子查詢計(jì)算累計(jì)和(由于不使用SUM OVER這類窗口函數(shù),因此就不能像在DB2和Oracle解決方案中那樣容易地按SAL給結(jié)果排序)。不管怎么說,累計(jì)和是正確的(最終結(jié)果與上一節(jié)相同),但由于沒有進(jìn)行排序,其中間值有所不同:

    1 select e.ename, e.sal,

    2         (select sum(d.sal) from emp d

    3           where d.empno <= e.empno) as running_total

    4    from emp e

    5   order by 3

    ENAME              SAL RUNNING_TOTAL

    ---------- ---------- -------------

    SMITH              800            800

    ALLEN             1600           2400

    WARD              1250           3650

    JONES             2975           6625

    MARTIN            1250           7875

    BLAKE             2850          10725

    CLARK             2450          13175

    SCOTT             3000          16175

    KING              5000          21175

    TURNER            1500          22675

    ADAMS             1100          23775

    JAMES              950          24725

    FORD              3000          27725

    MILLER            1300          29025

    討論

    生成累計(jì)和是因使用新的ANSI窗口函數(shù)而得以簡(jiǎn)化的任務(wù)之一。對(duì)于不支持這些窗口函數(shù)的DBMS,需要使用標(biāo)量子查詢(按取值唯一的字段聯(lián)接)。

    DB2和Oracle

    窗口函數(shù)SUM OVER能夠非常容易地生成累計(jì)和。該解決方案中的ORDER BY子句不僅包含SAL列,而且還包含EMPNO列(主鍵),以避免累計(jì)和中出現(xiàn)重復(fù)值。下面例子中的RUNNING_TOTAL2列示意了存在重復(fù)值時(shí)可能帶來的問題:

    select empno, sal,

            sum(sal)over(order by sal,empno) as running_total1,

            sum(sal)over(order by sal) as running_total2

       from emp

    order by 2

    ENAME              SAL RUNNING_TOTAL1 RUNNING_TOTAL2

    ---------- ---------- -------------- --------------

    SMITH              800             800             800

    JAMES              950            1750            1750

    ADAMS             1100            2850            2850

    WARD              1250            4100            5350

    MARTIN            1250            5350            5350

    MILLER            1300            6650            6650

    TURNER            1500            8150            8150

    ALLEN             1600            9750            9750

    CLARK             2450           12200           12200

    BLAKE             2850           15050           15050

    JONES             2975           18025           18025

    SCOTT             3000           21025           24025

    FORD              3000           24025           24025

    KING              5000           29025           29025

    對(duì)于WARD、MARTIN、SCOTT和FORD,RUNNING_TOTAL2中的值都不正確。他們的工資分別出現(xiàn)了多次,這些重復(fù)值都被加在一起計(jì)入累計(jì)和。這就是需要使用EMPNO(它是唯一的)才能生成與RUNNING_TOTAL1一樣的(正確)結(jié)果的原因。大家想一想:對(duì)于ADAMS,RUNNING_TOTAL1的值為2850,RUNNING_TOTAL2把WARD的工資1250與2850相加,應(yīng)該得到4100,然而,RUNNING_TOTAL2卻返回了5350,這是為什么呢?因?yàn)閃ARD和MARTIN的SAL相同,他們兩個(gè)的工資(1250)加在一起就等于2500,然后再加2850,就得到5350。如果指定按不會(huì)有重復(fù)值的列組合(例如,SAL和EMPNO的取值組合都是唯一的)排序,就能確保生成正確的累計(jì)和。

    MySQL、PostgreSQL和SQL Server

    在這些DBMS完全支持窗口函數(shù)之前,可以使用標(biāo)量子查詢計(jì)算累計(jì)和。一定要按取值唯一的列聯(lián)接,否則一旦存在像工資重復(fù)這樣的情況,就會(huì)產(chǎn)生不正確的累計(jì)和。本節(jié)解決方案的關(guān)鍵是把D.EMPNO與E.EMPNO聯(lián)接起來,它會(huì)返回(求和)每個(gè)滿足D.EMPNO小于或等于E.EMPNO D.SAL。為了更容易理解這些內(nèi)容,可以重新編寫標(biāo)量子查詢,把它寫成職員之間的聯(lián)接:

    select e.ename as ename1, e.empno as empno1, e.sal as sal1,

            d.ename as ename2, d.empno as empno2, d.sal as sal2

       from emp e, emp d

    where d.empno <= e.empno

        and e.empno = 7566

    ENAME           EMPNO1        SAL1 ENAME           EMPNO2        SAL2

    ---------- ---------- ---------- ---------- ---------- ----------

    JONES             7566        2975 SMITH             7369         800

    JONES             7566        2975 ALLEN             7499        1600

    JONES             7566        2975 WARD              7521        1250

    JONES             7566        2975 JONES             7566        2975

    EMPNO2中的每個(gè)值與EMPNO1中的每個(gè)值相比較。對(duì)于EMPNO2值小于等于EMPNO1值的所有行,都會(huì)把SAL2值加入總和。在這個(gè)例子中,職員Smith、Allen、Ward和Jones的EMPNO值都與Jones的EMPNO值相比較。由于這四個(gè)職員的EMPNO都滿足小于等于Jones的EMPNO的條件,所以會(huì)把這些工資加起來;而那些大于Jones的EMPNO的職員都不會(huì)計(jì)入SUM中。完整的查詢的計(jì)算方法是:將所有EMPNO小于等于7934(Miller的EMPNO,這個(gè)表中的最大值)的所有職員的工資加起來。

    posted on 2008-05-14 21:37 紙飛機(jī) 閱讀(7982) 評(píng)論(0)  編輯  收藏 所屬分類: Database
    主站蜘蛛池模板: 免费国产在线观看不卡| h视频在线观看免费网站| 免费毛片网站在线观看| 亚洲中文字幕久久精品无码VA| 免费成人福利视频| 亚洲中文字幕在线无码一区二区 | 久久久久亚洲AV无码专区体验| 永久免费不卡在线观看黄网站| 特黄特色的大片观看免费视频| 国产又大又粗又硬又长免费| 日韩亚洲人成网站| 亚洲美日韩Av中文字幕无码久久久妻妇| 亚洲精品国产高清不卡在线| 永久免费无码网站在线观看个| 亚洲天堂中文字幕在线| 久久这里只精品国产免费10| 亚洲成人黄色网址| 夫妻免费无码V看片| 麻豆一区二区三区蜜桃免费| 亚洲人成图片小说网站| 最近2018中文字幕免费视频| 亚洲色大成网站www尤物| 亚洲国产aⅴ综合网| 99视频在线免费| 亚洲欧洲无码AV不卡在线| 亚洲毛片网址在线观看中文字幕 | 亚洲?V乱码久久精品蜜桃| 久久一区二区免费播放| 亚洲日本香蕉视频观看视频| 在线jlzzjlzz免费播放| 三年片免费观看大全国语| 亚洲国产综合无码一区二区二三区| 精品国产污污免费网站入口在线 | 精品日韩亚洲AV无码| 国内免费高清在线观看| 一级毛片不卡免费看老司机| 亚洲国产日韩女人aaaaaa毛片在线| 国产一级高清视频免费看| 暖暖日本免费中文字幕| 日本亚洲欧美色视频在线播放| 亚洲va中文字幕无码久久|