SQL开窗函数

概念:

开窗函数是对于每条记录 都要在此窗口内执行函数,它对数据的每一行 ,都使用与该行相关的行进行计算并返回计算结果。开窗函数的本质还是聚合运算,只不过它更具灵活性。
开窗函数和普通聚合函数的区别:

  • 聚合函数是将多条记录聚合为一条;而开窗函数是每条记录都会执行,有几条记录执行完还是几条。
  • 聚合函数也可以用于开窗函数中。

应用:
窗口函数提供了在查询结果中进行排序、排名、聚合和分析的灵活性。窗口函数在数据分析和报表生成中非常有用,可以实现更复杂的计算和分析需求。

语法:

window_function() OVER (
[PARTITION BY partition_expression]
[ORDER BY order_list]
[frame_clause] )

开窗函数的一个概念是当前行,当前行属于某个窗口,窗口由over关键字用来指定函数执行的窗口范围,如果后面括号中什么都不写,则意味着窗口包含满足where条件的所行,开窗函数基于所有行进行计算;如果不为空,则有三个参数来设置窗口:

  • window_function(): 要使用的窗口函数,如:ROW_NUMBER(), RANK(), DENSE_RANK(), LEAD(), LAG(), SUM(), AVG() 等。
  • PARTITION BY: 可选项,用于将结果集划分为分区,以便窗口函数在每个分区内计算。
  • ORDER BY: 可选项,用于指定结果集的排序顺序,窗口函数将根据指定的排序顺序进行计算。
  • frame_clause: 可选项,用于指定窗口中要考虑的行的范围。常见的 frame 类型包括 ROWS, RANGE 等,通常用来作为滑动窗口使用。

对于滑动窗口的范围指定,通常使用 between frame_start and frame_end 语法来表示行范围,frame_start和frame_end可以支持如下关键字,来确定不同的动态行记录:

current row 边界是当前行,一般和其他范围关键字一起使用
unbounded preceding 边界是分区中的第一行
unbounded following 边界是分区中的最后一行
expr preceding 边界是当前行减去expr的值
expr following 边界是当前行加上expr的值

示例:

rows between 1 preceding and 1 following 窗口范围是当前行、前一行、后一行一共三行记录。
rows unbounded preceding 窗口范围是当前行到分区中的最后一行。
rows between unbounded preceding and unbounded following 窗口范围是当前分区中所有行,等同于不写。

在这里插入图片描述

常用的窗口函数及示例:

以下是一些MySQL中常用的窗口函数:
示例数据: 销售表包含以下列:销售部门、销售产品、销售日期、销售员、销售数量、产品单价;(销售额=销售数量*产品单价)

CREATE TABLE sales (
    department VARCHAR(50),
    product VARCHAR(50),
    sale_date DATE,
    salesperson VARCHAR(50),
    quantity INT,
    unit_price DECIMAL(10,2)
);

INSERT INTO sales (department, product, sale_date, salesperson, quantity, unit_price)
VALUES
('销售1部','1001','2024/5/3','王明','15','200'),
('销售2部','1002','2024/5/10','徐小小','20','500'),
('销售3部','1002','2024/5/18','纪风','10','500'),
('销售1部','1001','2024/5/5','王明','30','200'),
('销售2部','1002','2024/5/12','徐小小','25','500'),
('销售3部','1001','2024/5/20','纪风','18','200'),
('销售1部','1001','2024/5/8','王明','12','200'),
('销售2部','1002','2024/5/25','徐小小','22','500'),
('销售2部','1003','2024/5/15','徐小小','8','1000'),
('销售1部','1001','2024/5/30','王明','16','200'),
('销售2部','1002','2024/5/1','徐小小','14','500'),
('销售3部','1003','2024/5/22','纪风','19','1000'),
('销售2部','1001','2024/5/7','徐小小','21','200'),
('销售2部','1002','2024/5/28','刘阳','11','500'),
('销售3部','1003','2024/5/17','纪风','24','1000'),
('销售1部','1001','2024/5/4','王明','17','200'),
('销售2部','1002','2024/5/13','刘阳','9','500'),
('销售3部','1003','2024/5/21','纪风','23','1000'),
('销售1部','1001','2024/5/29','张一','7','200'),
('销售2部','1002','2024/5/6','刘阳','13','500'),
('销售3部','1003','2024/5/23','付华','18','1000'),
('销售1部','1001','2024/5/2','张一','20','200'),
('销售2部','1002','2024/5/9','刘阳','10','500'),
('销售3部','1003','2024/5/26','付华','30','1000'),
('销售1部','1001','2024/5/14','张一','25','200'),
('销售2部','1002','2024/5/31','刘阳','18','500'),
('销售3部','1003','2024/5/24','付华','12','1000'),
('销售1部','1001','2024/5/11','张一','22','200'),
('销售2部','1002','2024/5/19','刘阳','8','500'),
('销售3部','1003','2024/5/27','付华','16','1000'),
('销售1部','1001','2024/5/16','张一','14','200'),
('销售2部','1002','2024/5/3','刘阳','19','500'),
('销售3部','1003','2024/5/20','付华','21','1000'),
('销售1部','1001','2024/5/7','张一','11','200'),
('销售2部','1002','2024/5/24','刘阳','24','500'),
('销售3部','1003','2024/5/12','付华','17','1000'),
('销售1部','1001','2024/5/29','张一','9','200'),
('销售1部','1002','2024/5/5','张一','23','500'),
('销售2部','1003','2024/5/22','刘阳','7','1000'),
('销售3部','1001','2024/5/9','付华','13','200'),
('销售1部','1002','2024/5/16','张一','18','500'),
('销售2部','1003','2024/5/23','刘阳','20','1000'),
('销售3部','1001','2024/5/1','付华','10','200'),
('销售1部','1002','2024/5/18','张一','30','500'),
('销售2部','1003','2024/5/25','刘阳','25','1000'),
('销售3部','1001','2024/5/2','付华','18','200'),
('销售1部','1002','2024/5/11','张一','10','500'),
('销售2部','1003','2024/5/9','刘阳','50','1000'),
('销售3部','1001','2024/5/10','付华','5','200');

求平均值:AVG() :

查询各部门的平均销售额(需保留全部行信息)

SELECT *,quantity*unit_price as sale,avg(quantity*unit_price) over(partition by department ) avg_sale  from sales;
+-------+--------+-----------+------+------------+------+------+--------+-------
-----------+
|  department	|	product	|	sale_date	|	salesperson	|	quantity	|	unit_price	|	sale	|	avg_sale	|
|  销售1|	1001	|	2024/5/3	|	王明	|	15	|	200	|	3000	|	5006.25	|
|  销售1|	1001	|	2024/5/7	|	张一	|	11	|	200	|	2200	|	5006.25	|
|  销售1|	1001	|	2024/5/29	|	张一	|	9	|	200	|	1800	|	5006.25	|
|  销售1|	1001	|	2024/5/5	|	王明	|	30	|	200	|	6000	|	5006.25	|
|  销售1|	1001	|	2024/5/29	|	张一	|	7	|	200	|	1400	|	5006.25	|
|  销售1|	1002	|	2024/5/5	|	张一	|	23	|	500	|	11500	|	5006.25	|
|  销售1|	1001	|	2024/5/8	|	王明	|	12	|	200	|	2400	|	5006.25	|
|  销售1|	1002	|	2024/5/16	|	张一	|	18	|	500	|	9000	|	5006.25	|
|  销售1|	1001	|	2024/5/2	|	张一	|	20	|	200	|	4000	|	5006.25	|
|  销售1|	1001	|	2024/5/30	|	王明	|	16	|	200	|	3200	|	5006.25	|
|  销售1|	1002	|	2024/5/18	|	张一	|	30	|	500	|	15000	|	5006.25	|
|  销售1|	1002	|	2024/5/11	|	张一	|	10	|	500	|	5000	|	5006.25	|
|  销售1|	1001	|	2024/5/14	|	张一	|	25	|	200	|	5000	|	5006.25	|
|  销售1|	1001	|	2024/5/11	|	张一	|	22	|	200	|	4400	|	5006.25	|
|  销售1|	1001	|	2024/5/16	|	张一	|	14	|	200	|	2800	|	5006.25	|
|  销售1|	1001	|	2024/5/4	|	王明	|	17	|	200	|	3400	|	5006.25	|
|  销售2|	1002	|	2024/5/10	|	徐小小	|	20	|	500	|	10000	|	11705.55556	|
|  销售2|	1002	|	2024/5/6	|	刘阳	|	13	|	500	|	6500	|	11705.55556	|
|  销售2|	1002	|	2024/5/12	|	徐小小	|	25	|	500	|	12500	|	11705.55556	|
|  销售2|	1002	|	2024/5/13	|	刘阳	|	9	|	500	|	4500	|	11705.55556	|
|  销售2|	1002	|	2024/5/25	|	徐小小	|	22	|	500	|	11000	|	11705.55556	|
|  销售2|	1003	|	2024/5/15	|	徐小小	|	8	|	1000	|	8000	|	11705.55556	|
|  销售2|	1002	|	2024/5/1	|	徐小小	|	14	|	500	|	7000	|	11705.55556	|
|  销售2|	1002	|	2024/5/9	|	刘阳	|	10	|	500	|	5000	|	11705.55556	|
|  销售2|	1001	|	2024/5/7	|	徐小小	|	21	|	200	|	4200	|	11705.55556	|
|  销售2|	1002	|	2024/5/28	|	刘阳	|	11	|	500	|	5500	|	11705.55556	|
|  销售2|	1002	|	2024/5/31	|	刘阳	|	18	|	
  • 51
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值