mysql求和语句的用法_巧用sql进行数据累加

本文介绍了如何使用SQL查询来计算每个员工每月的累计薪水。通过创建User_Salary表并插入数据,展示了两种不同的SQL查询方法,一种使用子查询,另一种使用内部连接,以达到相同的效果——按月展示每个员工的薪水及其累计总额。
摘要由CSDN通过智能技术生成

比如有这样一个需求,一张表格(User_Salary)包含每个人(UserName)每个月份(Month)发的薪水(Salary)

求这样一个结果集:每个人每月所发薪水及累计所得薪水和,如下表

UserName

Month

Salary

AAA

2010/12

1000

AAA

2011/01

2000

AAA

2011/02

3000

BBB

2010/12

2000

BBB

2011/01

2500

BBB

2011/02

2500

结果

UserName

Month

Salary

Cumulation

AAA

2010/12

1000

1000

AAA

2011/01

2000

3000

AAA

2011/02

3000

6000

BBB

2010/12

2000

2000

BBB

2011/01

2500

4500

BBB

2011/02

2500

7000

当然这个结果在Excel中十分好实现,只需要一个公式就好:

502600eae2b35dd965a4142e004f3414.png

注意G2的公式一定要保持第一个列不动所以就是$F$2:F2,然后向下拖一下就可以,但是,这只适用于数据固定的情况下,试想,如果有100个员工的数据,岂不是要拖100下。当然也可能有其他办法,这个我就不知道了。

下面,如果用sql实现能有什么办法呢?首先想到的是游标。

对游标的确可以实现,写程序也可以实现,因为他们的思想是一样的:判断一下名字是不是已经遍历过了,如果遍历过了,就累加一下,如果没有就从0加起。这样很好理解,但是写的很费时,其实一条sql语句就可以实现的,那就是子查询。

1: create table User_Salary (UserName nvarchar(200), Month nvarchar(20), Salary int)

2:

3: go

4:

5: insert into User_Salary (UserName,Month,Salary ) values('AAA','2010/12',1000)

6: insert into User_Salary (UserName,Month,Salary ) values('AAA','2011/01',2000)

7: insert into User_Salary (UserName,Month,Salary ) values('AAA','2011/02',3000)

8: insert into User_Salary (UserName,Month,Salary ) values('BBB','2010/12',2000)

9: insert into User_Salary (UserName,Month,Salary ) values('BBB','2011/01',2500)

10: insert into User_Salary (UserName,Month,Salary ) values('BBB','2011/02',2500)

11:

12: go

13:

14: select UserName,Month,Salary,

15: Cummulation=(

16: select SUM(Salary)

17: from

18: User_Salary i

19: where

20: i.UserName=o.UserName and i.Month<=o.Month

21: )

22: from User_Salary o

23: order by 1,2

24:

25: go

26:

27: drop table User_Salary

大家知道SQL查询的结果是面向集合,而这种嵌套的子查询恰恰就是在整个结果集返回之前做的对于每一行的运算。也许这样的写法不是很容易理解,那么下面这个写法应该容易理解多了。

1: create table User_Salary (UserName nvarchar(200), Month nvarchar(20), Salary int)

2:

3: go

4:

5: insert into User_Salary (UserName,Month,Salary ) values('AAA','2010/12',1000)

6: insert into User_Salary (UserName,Month,Salary ) values('AAA','2011/01',2000)

7: insert into User_Salary (UserName,Month,Salary ) values('AAA','2011/02',3000)

8: insert into User_Salary (UserName,Month,Salary ) values('BBB','2010/12',2000)

9: insert into User_Salary (UserName,Month,Salary ) values('BBB','2011/01',2500)

10: insert into User_Salary (UserName,Month,Salary ) values('BBB','2011/02',2500)

11:

12: go

13:

14: select

15: A.UserName,A.Month,MAX(A.Salary) as Salary,SUM (B.Salary) as Accumulation

16: from

17: User_Salary A inner join User_Salary B

18: ON

19: A.UserName = B.UserName

20: where

21: B.Month <= A.Month

22: group by

23: A.UserName,A.Month

24: order by

25: A.UserName,A.Month

26:

27: go

28:

29: drop table User_Salary

这样用联合的方式就好理解一些,其实这样就是把每一行对应比他月份小的值分成一组,然后进行运算,如果这样不明白,那么下面的sql会使这个查询更加好理解:

1: select

2: A.*,B.*

3: from

4: User_Salary A inner join User_Salary B

5: ON

6: A.UserName = B.UserName

7: where

8: B.Month <= A.Month

9: order by 1,2

这样的结果就显而易见了

b90f98b41bef83638b864f28f0695fd5.png

这就是子查询相关的递归(可以这么说?)算法。

09a25d0532f2a59ceae4eded80ac64b8.png

子查询执行计划

f7250a7285bfe78618873994c8a1f909.png

join执行计划

通过上述2个执行计划,虽然执行计划不同,但大体一致,这其中的区别我就不太明白了(不知道是先排序再join好 还是先join在排序好,但是我个人觉得第二种比较容易理解.).

源代码

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值