【题目】

“薪水表”中记录了员工发放的薪水。包含雇员编号,薪水、起始日期、结束日期。

其中,薪水是指该雇员在起始日期到结束日期这段时间内的薪水。当前员工是指结束日期 = '9999-01-01'的员工。

业务问题:按照雇员编号升序排列,查找薪水的累计和(累计薪水)。其中累计薪水是前N个当前员工( 结束日期 = '9999-01-01')的薪水的累计和,其他以此类推。

【解题步骤】

1.先筛选出当前员工( 结束日期 = '9999-01-01')的薪水

select 雇员编号,薪水from 薪水表where 结束日期 = '9999-01-01'

查询结果

2.什么是累计薪水?

由题意可以看出输出结果需要包含薪水和累计薪水。累计薪水是前N个当前员工的薪水的累计和得出。

举个例子,如下图:

第1行的累计薪水为雇员编号(10001)的薪水,

第2行的累计薪水为雇员编号(10001)、雇员编号(10002)的薪水之和,

第3行的累计薪水为雇员编号(10001)、雇员编号(10002)、雇员编号(10003)的薪水之和

依次类推...

3.如何计算出每行的累计薪水?

(1)方法1,用窗口函数(推荐)

在《猴子 从零学会SQL》里讲过窗口函数的基本语法如下:

<窗口函数> over (partition by <用于分组的列名>                               order by <用于排序的列名>)

用聚合函数作为窗口函数,有累计的功能。因为本题是累计“求和”,所以用聚合函数sum。

select 雇员编号,薪水,sum(薪水) over (order by 雇员编号) as 累计薪水from 薪水表where 结束日期 = '9999-01-01';

查询结果

(2)方法2,用自联结(不推荐)

“薪水表”中只有“雇员编号”和“薪水表”,根据上述累计薪水的计算方法,

因此我们需要得到下图所示的表1才能计算累计薪水,左边是雇员编号以及对应的当前薪水,右边则是左边雇员编号对应的求累计薪水需要用到的雇员编号和薪水。

如计算左边雇员编号10002的累计薪水则需用到右边雇员编号(1)中10001和10002两人的当前薪水,且需要满足右边雇员编号(1)<=左边雇员编号

根据左边的雇员编号和薪水分组,再对右边的薪水(1)进行求和,即可得出每个雇员编号对应的累计薪水。

那么,上述的表是如何得出的呢?薪水表中只有一列雇员编号和一列薪水,因此我们需要复制一张薪水表并与原来的合并,需要用到自联结,语法如下:

select 列名 from 表名 as 别名1,表名 as 别名2;
select *from 薪水表 as s1,薪水表 as s2;

需要加上什么条件吗?显然观察上述图表,需满足雇员编号(1)<=雇员编号,而题意当前员工的薪水需要满足结束日期 = '9999-01-01',并按雇员编号升序排列:

select s1.雇员编号,s1.薪水,s2.雇员编号,s2.薪水from 薪水表 as s1,薪水表 as s2where s2.雇员编号 <= s1.雇员编号 and s1.结束日期 = '9999-01-01' and s2.结束日期 = '9999-01-01'order by s1.雇员编号;

最后用 group by 对雇员编号,薪水进行分组,并用 sum 函数对薪水(1)进行求和:

select s1.雇员编号,s1.薪水,sum(s2.薪水) as 累计薪水from 薪水表 as s1,薪水表 as s2where s2.雇员编号 <= s1.雇员编号 and s1.结束日期 = '9999-01-01' and s2.结束日期 = '9999-01-01'group by s1.雇员编号,s1.薪水order by s1.雇员编号;

【本题考点】

对于“累计”问题,要想到用聚合函数作为窗口函数。比如累计求和,用sum。

sum(列名) over (partition by <用于分组的列名>                               order by <用于排序的列名>)

累计求平均值,用avg。

avg(列名) over (partition by <用于分组的列名>                               order by <用于排序的列名>)

所以,我们可以得出“累计求和”问题的万能模板是:

select 列1,列2,sum(列2) over (order by 列1) as 累计值select 列1,列2,sum(列名) over (partition by                   order by ) as 累计值的别名from 表名;

【举一反三】

下表为确诊人数表,包含日期和该日期对应的新增确诊人数

按照日期进行升序排列,查找日期、确诊人数以及对应的累计确诊人数。

参考答案:

select 日期,确诊人数,sum(确诊人数) over (order by 日期) as 累计确诊人数from 确诊人数表;

查询结果

推荐:如何从零学会sql?

sql 列求和_图解面试题:累计求和问题如何分析?相关推荐

  1. oracle对某两列求和再求和_只会SUM函数求和,试试这5种求和函数,十倍提高工作效率...

    在平时的工作和学习中,求和计算算是比较司空见惯的数据统计方式,但大多数人只知道Sum函数可以用来求和,事实上,除了SUM函数,还有SUMIF.SUMIFS.SUBTOTAL.SUMPRODUCT.SU ...

  2. sql如何让计算出来的结果百分数显示_图解面试题:如何交换数据?

    [题目] 小明是一所学校的老师,她有一张 '学生表',平时用来存放座位号和学生的信息.其中,座位号是连续递增的.总的座位数是偶数. 现在,小明想改变相邻俩学生的座位.你能不能帮她写一个sql查来输出想 ...

  3. call 存储过程时必须声明表示符_图解面试题:SQL存储过程有什么用?

    面试中有时候会问:存储过程有什么用?看了今天的知识,你就知道如何回答了. 1.存储过程是什么? 假如你每天要开车完成一些列重复的操作:车钥匙启动车,倒车.现在出现了一款新车,可以自动的完成这些重复的工 ...

  4. sql 大于某个日期_图解面试题:如何比较日期数据?

    [题目] 下面是某公司每天的营业额,表名为"日销"."日期"这一列的数据类型是日期类型(date). 请找出所有比前一天(昨天)营业额更高的数据.(前一天的意思 ...

  5. sql server 中获取前一天日期_图解面试题:如何比较日期数据?

    ​[题目] 下面是某公司每天的营业额,表名为"日销"."日期"这一列的数据类型是日期类型(date). 请找出所有比前一天(昨天)营业额更高的数据.(前一天的意 ...

  6. 对应sql建表_图解SQL面试题:如何查找工资前三高的员工

    [题目] ​"成绩表"记录了学生的学号,学生选修的课程,以及对应课程的成绩. 为了对学生成绩进行考核,现需要查询每门课程的前3高成绩. 注意:如果出现并列第一的情况,则同为第一名. ...

  7. sql 过滤空值_图解 SQL,这简直太形象了吧!

    作者: 不剪发的Tony老师 来源:CSDN 链接:http://r6d.cn/qKD6 本文介绍关系数据库的设计思想:在 SQL 中,一切皆关系.在计算机领域有许多伟大的设计理念和思想,例如: 在 ...

  8. 求中位数_图解面试题:如何分析中位数?

    学校每次考试完,都会有一个成绩表.例如,表中第1行表示编号为1的用户选择了C++岗位,该科目考了11001分. 问题:写一个sql语句查询每个岗位的中位数位置的范围,并且按岗位升序排序,结果如下: 解 ...

  9. oracle如何判断奇数偶数_图解面试题:如何分析中位数?

    学校每次考试完,都会有一个成绩表.例如,表中第1行表示编号为1的用户选择了C++岗位,该科目考了11001分. 问题:写一个sql语句查询每个岗位的中位数位置的范围,并且按岗位升序排序,结果如下: 解 ...

最新文章

  1. 在Ubuntu kylin 14 64位上flashplayer 插件
  2. 经典角点检测算法实现
  3. 对移动APP开发的需求分析的观点及见解
  4. Linux动态频率调节系统CPUFreq
  5. C语言分区排序partition sort 算法(附完整源码)
  6. 串的块链存储c语言栈,小蚂蚁学习数据结构(18)——串的块链的代码实现
  7. linux安装之后缺少命令,Centos 7 最小安装后关键命令找不到 ifconfig等
  8. Javascript节点的访问
  9. ~~Kruskal算法
  10. 给定一个数组A[0,1,...,n-1],请构建一个数组B[0,1,...,n-1],其中B中的元素B[i]=A[0]*A[1]*...*A[i-1]*A[i+1]*...*A[n-1](简单易懂)
  11. C++工程通过opencv找到自己定义的矩形中的两平行线的距离
  12. Atitit mysql存储过程编写指南 1. 定义变量 1 1.1. 变量名以@开头用户变量 会话变量 1 1.2. 以declare关键字声明 存储过程变量 2 1.3. @是用户自定义变量,
  13. linux嗅探网站结构,Linux下的Dsniff嗅探浅析
  14. 网络和计算机加密解密感叹号,网络连接显示感叹号但是能上网怎么办 网络连接显示感叹号原因【图文】...
  15. 使用c++实现复数类的运算
  16. cocos creator移动事件和 opacity
  17. kafak学习之分享ppt
  18. heritrix java_爬虫技术框架——Heritrix
  19. SM社区医院健康管理网站
  20. 创建mysql数据库快照_创建数据库快照 (Transact-SQL)

热门文章

  1. html5微信视频禁止自动全屏,关于HTML5 video标签在安卓版微信浏览器内被强行全屏播放的问题...
  2. 华为p4支持鸿蒙功能吗_什么样的手机可以刷鸿蒙系统?看看你的手机支持吗?...
  3. 亚麻纤维截面形态_纺织品知识点--纺织纤维的分类get
  4. java 异常返回json_Spring MVC全局异常后返回JSON异常数据
  5. C语言为四维数组申请动态内存空间的方法(一)
  6. CoreOS ignition简介
  7. MultiMedia eXtensions - MMX:第一套应用于英特尔 80x86 指令集的 SIMD 扩展
  8. 【转】VLAN(Virtual LAN)“虚拟局域网”
  9. Linux的TUN/TAP编程
  10. Java native方法String转char*以及String[]转char**