SQL的各种SUM,示例看用group by、partition by的实现方式

一、示例数据

员工信息表,包括字段有:员工姓名、省份、城市、年龄、薪水

CREATE TABLE TMP_Person (PName VARCHAR2(20),PProvince VARCHAR2(20),Pcity VARCHAR2(20),PAge INT,PSalary INT)
INSERT INTO TMP_Person(PName,PProvince,Pcity,PAge,PSalary)
VALUES('A','GuangDong','ShenZhen',20,3000);
INSERT INTO TMP_Person(PName,PProvince,Pcity,PAge,PSalary)
VALUES('B','GuangDong','ShenZhen',21,4000);
INSERT INTO TMP_Person(PName,PProvince,Pcity,PAge,PSalary)
VALUES('C','GuangDong','ShenZhen',22,3500);
INSERT INTO TMP_Person(PName,PProvince,Pcity,PAge,PSalary)
VALUES('D','GuangDong','ShenZhen',21,2000);
INSERT INTO TMP_Person(PName,PProvince,Pcity,PAge,PSalary)
VALUES('E','GuangDong','GuangZhou',22,1000);
INSERT INTO TMP_Person(PName,PProvince,Pcity,PAge,PSalary)
VALUES('F','GuangDong','GuangZhou',20,3000);
INSERT INTO TMP_Person(PName,PProvince,Pcity,PAge,PSalary)
VALUES('G','GuangDong','GuangZhou',22,2000);
INSERT INTO TMP_Person(PName,PProvince,Pcity,PAge,PSalary)
VALUES('H','GuangDong','DongGuan',20,2800);
INSERT INTO TMP_Person(PName,PProvince,Pcity,PAge,PSalary)
VALUES('I','GuangDong','DongGuan',24,8000);
INSERT INTO TMP_Person(PName,PProvince,Pcity,PAge,PSalary)
VALUES('J','GuangDong','DongGuan',25,8500);
INSERT INTO TMP_Person(PName,PProvince,Pcity,PAge,PSalary)
VALUES('K','GuangDong','DongGuan',22,3000);
INSERT INTO TMP_Person(PName,PProvince,Pcity,PAge,PSalary)
VALUES('L','JiangSu','NanTong',23,3500);
INSERT INTO TMP_Person(PName,PProvince,Pcity,PAge,PSalary)
VALUES('M','JiangSu','NanTong',30,3000);
INSERT INTO TMP_Person(PName,PProvince,Pcity,PAge,PSalary)
VALUES('N','JiangSu','NanTong',25,2000);
INSERT INTO TMP_Person(PName,PProvince,Pcity,PAge,PSalary)
VALUES('O','JiangSu','WuXi',24,3300);
INSERT INTO TMP_Person(PName,PProvince,Pcity,PAge,PSalary)
VALUES('P','JiangSu','WuXi',24,3300);
INSERT INTO TMP_Person(PName,PProvince,Pcity,PAge,PSalary)
VALUES('Q','JiangSu','WuXi',24,3300);

二、汇总输出每个城市的工资

  • group by方式
select PProvince,Pcity,sum(PSalary) 
from TMP_Person 
group by PProvince,Pcity

  • partition by方式
select distinct PProvince,Pcity,sum(PSalary) over (partition by PProvince,Pcity) 
from TMP_Person 

三、计算每个城市在该省的工资占比

分析:输出的记录是按每个城市一行。第一步需要汇总计算每个城市的汇总工资;第二步需要计算该城市对应省份的汇总工资

;最后将第一步结果除以第二步结果得出占比

  • group by方式

由于汇总城市工资、汇总省份工资,是属于不同层级的汇总,无法在一个group by条件下完成处理。需要使用子查询的方式完成。

select PProvince,Pcity,
sum(PSalary),    --分子
(select sum(PSalary) from TMP_Person b where b.pprovince=a.pprovince),    --分母
round(sum(PSalary)/(select sum(PSalary) from TMP_Person b where b.pprovince=a.pprovince),2)*100||'%' --占比
from TMP_Person a
group by PProvince,Pcity 

  • partition by方式

使用partition by计算分母,实现不同层级的汇总计算。

sum(sum(PSalary)) over (partition by PProvince)中,sum(PSalary)先按group by PProvince,Pcity汇总计算了每个城市的工资,再以PProvince开窗,继续sum一次前面计算出来的城市汇总的工资,实现汇总省份的工资。

select PProvince,Pcity,

sum(PSalary),    --分子

sum(sum(PSalary)) over (partition by PProvince),    --分母

round(sum(PSalary)/sum(sum(PSalary)) over (partition by PProvince),2)*100||'%' --占比

from TMP_Person

group by PProvince,Pcity

四、计算每个城市中,比当等于或小于前员工年龄的员工的薪金总和

  • group by方式

属于不同层级的汇总,需要子查询实现

select PName,PProvince,Pcity,PAge,PSalary,
(select sum(PSalary) from TMP_Person b 
where b.pcity=a.pcity and b.page<=a.page group by pcity)
from TMP_Person a

  • partition by方式

使用order by,sum排序在当前行之前的所有行的工资

select PName,PProvince,Pcity,PAge,PSalary,
sum(PSalary) over (partition by pcity order by page) 
from TMP_Person 
order by PName

原创文章 47 获赞 13 访问量 8242

猜你喜欢

转载自blog.csdn.net/scut_yfli/article/details/105521022