mysql求累计值_SQL语句-计算累加值
问题:计算某个列中所有值的累计和
解决⽅案
下⾯给出了⼀种解决⽅案,它展⽰了如何计算所有职员⼯资的累计和。为增加可读性,其结果是按SAL排序的,这样就能够很容易地观察到累计和变化的过程。
DB2和Oracle
使⽤窗⼝版本的SUM函数计算累计和:
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
mysql语句转oracleFORD              3000          24025
KING              5000          29025
MySQL、PostgreSQL和SQL Server
使⽤标量⼦查询计算累计和(由于不使⽤SUM OVER这类窗⼝函数,因此就不能像在DB2和Oracle解决⽅案中那样容易地按SAL给结果排序)。不管怎么说,累计和是正确的(最终结果与上⼀节相同),但由于没有进⾏排序,其中间值有所不同:
1 ame, e.sal,
2        (select sum(d.sal) from emp d
3          pno <= e.empno) as running_total
4    from emp e
yvonne这个名字罕见吗
5  order by 3
ENAME              SAL RUNNING_TOTAL
---------- ---------- -------------
SMITH              800            800
ALLEN            1600          2400
WARD              1250          3650
JONES            2975          6625transphorm怎么读
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
讨论
近的网站系统⽣成累计和是因使⽤新的ANSI窗⼝函数⽽得以简化的任务之⼀。对于不⽀持这些窗⼝函数的DBMS,需要使⽤标量⼦查询(按取值唯⼀的字段联接)。
DB2和Oracle
窗⼝函数SUM OVER能够⾮常容易地⽣成累计和。该解决⽅案中的ORDER BY⼦句不仅包含SAL列,⽽且还包含EMPNO列(主键),以避免累计和中出现重复值。下⾯例⼦中的RUNNING_TOTAL2列⽰意
了存在重复值时可能带来的问题:
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
对于WARD、MARTIN、SCOTT和FORD,RUNNING_TOTAL2中的值都不正确。他们的⼯资分别出现了多次,这些重复值都被加在⼀起计⼊累计和。这就是需要使⽤EMPNO(它是唯⼀的)才能⽣成与RUNNING_TOTAL1⼀样的(正确)结果的原因。⼤家想⼀想:对于ADAMS,RUNNING_TOTAL1的值为2850,RUNNING_TOTAL2把WARD的⼯资1250与2850相加,应该得到4100,然
⽽,RUNNING_TOTAL2却返回了5350,这是为什么呢?因为WARD和MARTIN的SAL相同,他们两个的⼯资(1250)加在⼀起就等于2500,然后再加2850,就得到5350。如果指定按不会有重复值的列组合(例如,SAL和EMPNO的取值组合都是唯⼀的)排序,就能确保⽣成正确的累计和。
MySQL、PostgreSQL和SQL Server
在这些DBMS完全⽀持窗⼝函数之前,可以使⽤标量⼦查询计算累计和。⼀定要按取值唯⼀的列联接,否则⼀旦存在像⼯资重复这样的情况,就会产⽣不正确的累计和。本节解决⽅案的关键是把D.EMPNO与E.EMPNO联接起来,它会返回(求和)每个满⾜D.EMPNO⼩于或等于E.EMPNO D.SAL。为了更容易理解这些内容,可以重新编写标量⼦查询,把它写成职员之间的联接:
ame as ename1, e.empno as empno1, e.sal as sal1,
from emp e, emp d
pno <= e.empno
pno = 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中的每个值与EMPNO1中的每个值相⽐较。对于EMPNO2值⼩于等于EMPNO1值的所有⾏,都会把SAL2值加⼊总和。在这个例⼦中,职员Smith、Allen、Ward和Jones的EMPNO值都与Jones的EMPNO值相⽐较。由于这四个职员的EMPNO都满⾜⼩于等于Jones的EMPNO的条件,所以
会把这些⼯资加起来;⽽那些⼤于Jones的EMPNO的职员都不会计⼊SUM中。完整的查询的计算⽅法是:将所有EMPNO⼩于等于7934(Miller的EMPNO,这个表中的最⼤值)的所有职员的⼯资加起来。