sql开窗函数

用的Oracle数据库进行测试

一、数据准备

DROP TABLE T_TEST;
CREATE TABLE T_TEST (
  id NUMBER(10) VISIBLE NOT NULL ,
  姓名 VARCHAR2(50 BYTE) VISIBLE ,
  性别 VARCHAR2(50 BYTE) VISIBLE ,
  班级 VARCHAR2(50 BYTE) VISIBLE ,
  成绩 NUMBER(5,2) VISIBLE 
);

INSERT INTO T_TEST VALUES ('1', '张三', '男', '1班', '100');
INSERT INTO T_TEST VALUES ('2', '李四', '男', '1班', '89');
INSERT INTO T_TEST VALUES ('3', '王五', '男', '1班', '70');
INSERT INTO T_TEST VALUES ('4', '浩宇', '男', '2班', '99');
INSERT INTO T_TEST VALUES ('5', '祥康', '男', '2班', '66');
INSERT INTO T_TEST VALUES ('6', '刘丽', '女', '2班', '88');
INSERT INTO T_TEST VALUES ('7', '张三', '男', '3班', '59');
INSERT INTO T_TEST VALUES ('8', '张三', '男', '4班', '78');

二、开窗函数是什么?

开窗函数是对一组值进行操作,不需要使用GROUP BY子句对数据进行分组,能够在同一行中同时返回基础行的列和聚合列。

三、开窗函数的语法

OVER( PARTITION BY 列名1 ORDER BY 列名2 )

括号中的两个关键词PARTITION BYORDER BY 可以只出现一个

四、开窗函数的类型?

聚合开窗

SUM(expr)

返回分组中的和

AVG(expr)

返回分组中的平均值

MIN(expr)

返回分组中的最小值

MAX(expr)

返回分组中的最大值

COUNT(expr)

返回分组中的行数

排序开窗

ROW_NUMBER()

分组排序,然后进行编号:1,2,3,4,5

RANK()

分组排序,然后进行编号,对相同值处理,跳号:1,1,3,4,5

DENSE_RANK()

分组排序,然后进行编号,对相同值处理,不跳号:1,1,2,3,4

偏移开窗

LAG(expr,n)

返回当前行的前n行的expr的值

LEAD(expr,n)

返回当前行的后n行的expr的值

FIRST_VALUE(expr)

返回第一个expr的值

LAST_VALUE(expr)

返回最后一个expr的值

五、开窗函数的演示

1、聚合开窗

① :SUM(expr)

语法:SUM(成绩) OVER( PARTITION BY 姓名 ORDER BY 班级 ASC )

描述:根据【姓名】分组,【班级】排序,然后对每个分组后的【成绩】进行求和操作。

SELECT 姓名,性别,班级,成绩, SUM(成绩) OVER(PARTITION BY 姓名 ORDER BY 班级 ASC) SUM_OVER FROM T_TEST

②:AVG(expr)

语法:AVG(成绩) OVER( PARTITION BY 姓名 ORDER BY 班级 ASC )

描述:根据【姓名】分组,【班级】排序,然后对每个分组后的【成绩】进行求平均值操作。

SELECT 姓名,性别,班级,成绩, AVG(成绩) OVER(PARTITION BY 姓名 ORDER BY 班级 ASC) AVG_OVER FROM T_TEST

③:MIN(expr)

语法:MIN(成绩) OVER( PARTITION BY 姓名 ORDER BY 班级 ASC )

描述:根据【姓名】分组,【班级】排序,然后对每个分组后的【成绩】进行求最小值的操作。

SELECT 姓名,性别,班级,成绩, MIN(成绩) OVER(PARTITION BY 姓名 ORDER BY 班级 ASC) MIN_OVER FROM T_TEST

④:MAX(expr)

语法:MAX(成绩) OVER( PARTITION BY 姓名 ORDER BY 班级 ASC )

描述:根据【姓名】分组,【班级】排序,然后对每个分组后的【成绩】进行求最最大值的操作。

SELECT 姓名,性别,班级,成绩, MAX(成绩) OVER(PARTITION BY 姓名 ORDER BY 班级 DESC) MAX_OVER FROM T_TEST

⑤:COUNT

语法:COUNT(成绩) OVER( PARTITION BY 姓名 ORDER BY 班级 ASC )

描述:根据【姓名】分组,【班级】排序,然后对每个分组后的【成绩】进行行数求和的操作。

SELECT 姓名,性别,班级,成绩, COUNT(成绩) OVER(PARTITION BY 姓名 ORDER BY 班级 DESC) COUNT_OVER FROM T_TEST

2、排序开窗

①:ROW_NUMBER()

语法:ROW_NUMBER() OVER(PARTITION BY 姓名 ORDER BY 成绩 DESC)

描述:根据【姓名】分组,【成绩】排序,然后进行数据行编号【1,2,3,4,5】。

SELECT 姓名,性别,班级,成绩, ROW_NUMBER() OVER(PARTITION BY 姓名 ORDER BY 成绩 DESC) ROW_NUMBER_OVER FROM T_TEST

②:RANK

语法:RANK() OVER(PARTITION BY 姓名 ORDER BY 成绩 DESC)

描述:根据【姓名】分组,【成绩】排序,然后进行数据行编号,遇到相同值,编号一样,下一个跳号【1,2,3,3,5】。

INSERT INTO T_TEST VALUES ('9', '金华', '男', '1班', '70');
INSERT INTO T_TEST VALUES ('10', '金华', '男', '1班', '60');

SELECT 姓名,性别,班级,成绩, RANK() OVER(PARTITION BY 班级 ORDER BY 成绩 DESC) RANK_OVER FROM T_TEST

③:DENSE_RANK

语法:DENSE_RANK() OVER(PARTITION BY 姓名 ORDER BY 成绩 DESC)

描述:根据【姓名】分组,【成绩】排序,然后进行数据行编号,遇到相同值,编号一样,下一个不跳号【1,2,3,3,4】。

SELECT 姓名,性别,班级,成绩, DENSE_RANK() OVER(PARTITION BY 班级 ORDER BY 成绩 DESC) DENSE_RANK_OVER FROM T_TEST

3、偏移开窗

①:LAG(expr,n)

语法:LAG(成绩,1) OVER(PARTITION BY 班级 ORDER BY 成绩 DESC)

描述:根据【班级】分组,【成绩】排序,然后返回当前行的前1行的成绩的值进行数据

SELECT 姓名,性别,班级,成绩, LAG(成绩,1) OVER(PARTITION BY 班级 ORDER BY 成绩 DESC) LAG_OVER FROM T_TEST

②:LEAD(expr,n)

语法:LEAD(成绩,1) OVER(PARTITION BY 班级 ORDER BY 成绩 DESC)

描述:根据【班级】分组,【成绩】排序,然后返回当前行的后1行的成绩的值

SELECT 姓名,性别,班级,成绩, LEAD(成绩,1) OVER(PARTITION BY 班级 ORDER BY 成绩 DESC) LEAD_OVER FROM T_TEST

③:FIRST_VALUE(expr)

语法:FIRST_VALUE(成绩) OVER(PARTITION BY 班级 ORDER BY 成绩 DESC)

描述:根据【班级】分组,【成绩】排序,然后返回当前组的第一个成绩的值

SELECT 姓名,性别,班级,成绩, FIRST_VALUE(成绩) OVER(PARTITION BY 班级 ORDER BY 成绩 DESC) FIRST_VALUE_OVER FROM T_TEST

④:LAST_VALUE

语法:LAST_VALUE(成绩) OVER(PARTITION BY 班级 ORDER BY 成绩 DESC)

描述:根据【班级】分组,【成绩】排序,然后返回当前组的最后一个成绩的值

SELECT 姓名,性别,班级,成绩, LAST_VALUE(成绩) OVER(PARTITION BY 班级 ORDER BY 成绩 DESC) LAST_VALUE_OVER FROM T_TEST

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值