好多次笔试面试的题都考到开窗函数,若对开窗函数不了解,真的吃了好大的亏,今天花点时间整理一下。
此文章整理的知识点部分来自:https://www.cnblogs.com/lihaoyang/p/6756956.html
1.开窗函数简介
与聚合函数一样,开窗函数也是对行集组进行聚合计算,但是它不像普通聚合函数那样每组只返回一个值,开窗函数可以为每组返回多个值,因为开窗函数所执行聚合计。
开窗函数格式: 函数名(列) OVER(选项)
OVER 关键字表示把函数当成开窗函数而不是聚合函数。
SQL 标准允许将所有聚合函数用做开窗函数,使用 OVER 关键字来区分这两种用法。
开窗函数 COUNT() OVER()
对于查询结果的每一行都返回所有符合条件的行的条数。OVER 关键字后的括号中还经常添加选项用以改变进行聚合运算的窗口范围。如果 OVER 关键字后的括号中的选项为空,则开窗函数会对结果集中的所有行进行聚合运算。
2. 开窗函数的使用实例
数据库表
CREATE TABLE T_Person (
FName VARCHAR2(20),
FCity VARCHAR2(20),
FAge INT,
FSalary INT);
在表中插入数据:
INSERT INTO T_Person(FName,FCity,FAge,FSalary)
VALUES('Tom','BeiJing',20,3000);
INSERT INTO T_Person(FName,FCity,FAge,FSalary)
VALUES('Tim','ChengDu',21,4000);
INSERT INTO T_Person(FName,FCity,FAge,FSalary)
VALUES('Jim','BeiJing',22,3500);
INSERT INTO T_Person(FName,FCity,FAge,FSalary)
VALUES('Lily','London',21,2000);
INSERT INTO T_Person(FName,FCity,FAge,FSalary)
VALUES('John','NewYork',22,1000);
INSERT INTO T_Person(FName,FCity,FAge,FSalary)
VALUES('YaoMing','BeiJing',20,3000);
INSERT INTO T_Person(FName,FCity,FAge,FSalary)
VALUES('Swing','London',22,2000);
INSERT INTO T_Person(FName,FCity,FAge,FSalary)
VALUES('Guo','NewYork',20,2800);
INSERT INTO T_Person(FName,FCity,FAge,FSalary)
VALUES('YuQian','BeiJing',24,8000);
INSERT INTO T_Person(FName,FCity,FAge,FSalary)
VALUES('Ketty','London',25,8500);
INSERT INTO T_Person(FName,FCity,FAge,FSalary)
VALUES('Kitty','ChengDu',25,3000);
INSERT INTO T_Person(FName,FCity,FAge,FSalary)
VALUES('Merry','BeiJing',23,3500);
INSERT INTO T_Person(FName,FCity,FAge,FSalary)
VALUES('Smith','ChengDu',30,3000);
INSERT INTO T_Person(FName,FCity,FAge,FSalary)
VALUES('Bill','BeiJing',25,2000);
INSERT INTO T_Person(FName,FCity,FAge,FSalary)
VALUES('Jerry','NewYork',24,3300);
计算人的总数量
select count(Fname)
from T_Person
查询工资小于5000的每个员工的具体信息
select *
from T_Person
where FSalary < 5000
查询每个人员的信息以及所在城市人数
select FName,
FCity,
FAge INT,
FSalary,
count(*) over(partition by FCity ) as 所在城市人数
查询每一个人员的信息、所在城市人数以及同龄人的人数
(使用多个开窗函数)
select Fname,
Fcity,
Fsalary,
count(*) over (partition by Fcity) as 所在城市人数,
count(*) over (partition by Fage) as 同龄人个数
from T_Person
查询从第一行到当前行的工资总和
(RANGE:
ROWS BETWEEN 边界规则1 AND 边界规则2”
用来定位聚合计算范围,这个子句又被称为定位框架)
select fname,
fcity,
fage,
fsalary,
sum(fsalary) over(order by fsalary rows between unbounded preceding and current row) 到当前行工资求和
from t_person
计算工资排名
select Fname, rank() over(order by(Fsalary) desc) as 工资排名
from t_person
order by 工资排名
查询同龄人中工资最高的员工信息,按工资排序
over(partition by XX order by XX) partition by和order by 结合