SQL之累计和及累计差详解
来源:互联网 发布:数据控制 编辑:程序博客网 时间:2024/04/25 05:19
在业务需要中,尤其是在日常的结算中,会进行累积和和累计差的求值,那么遇到该类业务该如何处理呢?
首先看一下累积和的问题。
在Oracle中,有表emp表,记录了员工的详细信息,其中有sal一列,那么
需求来了,
需求,
我们要累计各个部门员工总工资的姓名(ename)和员工编号(empno)
在Oracle中,对于此类问题oracle提供了分析函数。
累计求和的当然需要使用到sum函数。首先来看以下官方文档中的sum
SUMSUM([ DISTINCT | ALL ] expr) [ OVER (analytic_clause) ]
可以看到distinct |all|expr都是可选参数 over也是可选参数,其中的这个over就是oracle提供的分析函数。现在来做这个需求。
SQL> select ename 员工姓名,empno 员工编号,sum(sal) over(order by empno) 累积工资 2 from emp 3 order by empno;员工姓名 员工编号 累积工资---------- -------- ----------SMITH 7369 800ALLEN 7499 2400WARD 7521 3650JONES 7566 6625MARTIN 7654 7875BLAKE 7698 10725CLARK 7782 13175SCOTT 7788 16175KING 7839 21175TURNER 7844 22675ADAMS 7876 23775JAMES 7900 24725FORD 7902 27725MILLER 7934 2902514 rows selectedSQL>
这样就可以看到具体的累积工资之和了。但是这么看还不清晰,我们使用Oracle提供的listagg函数可以处理一下。
SQL> select ename 员工姓名,empno 员工编号,sum(sal) over(order by empno) 累积工资, 2 (select listagg(sal,'+') within group(order by empno) from emp b where b.empno<=a.empno) 计算公式, 3 (select listagg(ename,'+') within group(order by empno) from emp c where c.empno<=a.empno) 员工累计信息 4 from emp a 5 order by empno;员工姓名 员工编号 累积工资 计算公式 员工累计信息---------- -------- ---------- -------------------------------------------------------------------------------- --------------------------------------------------------------------------------SMITH 7369 800 800 SMITHALLEN 7499 2400 800+1600 SMITH+ALLENWARD 7521 3650 800+1600+1250 SMITH+ALLEN+WARDJONES 7566 6625 800+1600+1250+2975 SMITH+ALLEN+WARD+JONESMARTIN 7654 7875 800+1600+1250+2975+1250 SMITH+ALLEN+WARD+JONES+MARTINBLAKE 7698 10725 800+1600+1250+2975+1250+2850 SMITH+ALLEN+WARD+JONES+MARTIN+BLAKECLARK 7782 13175 800+1600+1250+2975+1250+2850+2450 SMITH+ALLEN+WARD+JONES+MARTIN+BLAKE+CLARKSCOTT 7788 16175 800+1600+1250+2975+1250+2850+2450+3000 SMITH+ALLEN+WARD+JONES+MARTIN+BLAKE+CLARK+SCOTTKING 7839 21175 800+1600+1250+2975+1250+2850+2450+3000+5000 SMITH+ALLEN+WARD+JONES+MARTIN+BLAKE+CLARK+SCOTT+KINGTURNER 7844 22675 800+1600+1250+2975+1250+2850+2450+3000+5000+1500 SMITH+ALLEN+WARD+JONES+MARTIN+BLAKE+CLARK+SCOTT+KING+TURNERADAMS 7876 23775 800+1600+1250+2975+1250+2850+2450+3000+5000+1500+1100 SMITH+ALLEN+WARD+JONES+MARTIN+BLAKE+CLARK+SCOTT+KING+TURNER+ADAMSJAMES 7900 24725 800+1600+1250+2975+1250+2850+2450+3000+5000+1500+1100+950 SMITH+ALLEN+WARD+JONES+MARTIN+BLAKE+CLARK+SCOTT+KING+TURNER+ADAMS+JAMESFORD 7902 27725 800+1600+1250+2975+1250+2850+2450+3000+5000+1500+1100+950+3000 SMITH+ALLEN+WARD+JONES+MARTIN+BLAKE+CLARK+SCOTT+KING+TURNER+ADAMS+JAMES+FORDMILLER 7934 29025 800+1600+1250+2975+1250+2850+2450+3000+5000+1500+1100+950+3000+1300 SMITH+ALLEN+WARD+JONES+MARTIN+BLAKE+CLARK+SCOTT+KING+TURNER+ADAMS+JAMES+FORD+MIL14 rows selectedSQL>
这样看起来就比较明白了。
除了分析函数,还可以使用开窗函数和标量来写,不过代价会比分析函数高,因为需要访问两次表,这里就不做了。
计算累计差
SQL> create or replace view v_detail 2 as 3 select rownum seq,a.* 4 from (select 编号,项目,金额 from detail order by 编号) a;View createdSQL> select * from v_detail; SEQ 编号 项目 金额---------- ---------- ------------ ---------- 1 1000 预交费用 30000 2 7782 支出1 3450 3 7839 支出2 6000 4 7934 支出3 2300SQL> select 编号,项目,金额, 2 (case when seq=1 then 金额 else -金额 end ) 转换后的值 from v_detail; 编号 项目 金额 转换后的值---------- ------------ ---------- ---------- 1000 预交费用 30000 30000 7782 支出1 3450 -3450 7839 支出2 6000 -6000 7934 支出3 2300 -2300SQL> with x as 2 (select rownum seq ,a.* 3 from (select 编号,项目,金额 from detail order by 编号) a) 4 select 编号,项目,金额, 5 (case when seq=1 then 金额 else -金额 end ) 转换后的值 from x; 编号 项目 金额 转换后的值---------- ------------ ---------- ---------- 1000 预交费用 30000 30000 7782 支出1 3450 -3450 7839 支出2 6000 -6000 7934 支出3 2300 -2300
现在开始计算累计差。
在这里说一下with x的用法,如果使用with x的写法,那就完全没有必要建立视图v_detail了,因为with x中的x就是一个视图,只是这个视图是临时的,如果查询结束,这个视图也就跟着消失了。
SQL> with x as 2 (select rownum seq,a.* 3 from (select 编号,项目,金额 from detail order by 编号) a) 4 select 编号,项目,金额, 5 sum(case when seq = 1 then 金额 else -金额 end ) over(order by seq) 余额 6 from x; 编号 项目 金额 余额---------- ------------ ---------- ---------- 1000 预交费用 30000 30000 7782 支出1 3450 26550 7839 支出2 6000 20550 7934 支出3 2300 18250SQL>
以上就是累计和和差的业务解析。
阅读全文
0 0
- SQL之累计和及累计差详解
- 累计
- ORACLE计算累计差
- 计算累计差
- sql 显示当日业绩和累计业绩
- sql server 点滴累计
- SQL 求按日累计
- ORACLE计算累计和
- 帮朋友写的一个累计SQL代码,有分季度,和总累计
- Sql Server累计求和问题
- 使用SQL查询累计值
- sql 循环累计一个按日期的和
- 求开始累计、年初到本期累计的SQL
- 单位净值和累计净值
- Callable和Future线程累计
- 日收益率和累计收益
- 累计日产
- 数字累计
- 习题五第三小题
- 2116 数据结构实验之链表一:顺序建立链表
- CodeForces
- 前端学习(十七)HTML的空格
- MongDB副本集(一),SpringBoot链接Mongo副本集
- SQL之累计和及累计差详解
- 【EFI系统分区】关于EFI系统分区的说明
- JavaBean作用范围
- javascript函数
- Git:your branch is up-to-date
- Codeforces 864F Round#436 F :有向图倍增
- 通过零拷贝实现高效的数据传输
- 编译原理与编译构造 二义文法
- Ajax