基本概念

MYSQL8.0支持窗口函数(Window Function),也称分析函数。窗口函数与组分聚合函数类似,但是每一行数据都会生成一个结果。如果我们将mysql与pandas中的DataFrame做类比学习的话他们的对应关系如下:

  • SQL分组聚合函数对应 => df.groupby([‘分组字段’])[‘目标’].agg()/apply()
  • SQL开窗函数对应 => df.groupby([‘分组字段’])[‘目标’].transform()

所以以下函数:SUM/AVG/COUNT/MAX/MIN等既能做聚合函数又能做窗口函数,可称聚合窗口函数。

如果对pandas的DataFrame中agg()/apply()/transform()这三个方法比较清楚的小伙伴,下面学习开窗函数会特别简单。

窗口函数表达式

function(args)over(
    partition by …
    order by… [desc]
    frame
)

  • partition by:按照指定字段进行分区,两个分区由边界分隔,开窗函数在不同的分区内分别执行,在跨越分区边界时重新初始化。
  • order by:按照指定字段进行排序,开窗函数将按照排序后的记录顺序进行编号。可以和partition
    by子句配合使用,也可以单独使用。
  • frame:当前分区的一个子集,用来定义子集的规则,通常用来作为滑动窗口使用。

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

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

窗口函数之-排序函数

  • row_number() :序号不重复,序号连续
  • dense_rank() :序号可以重复,序号连续
  • rank() :序号可以重复,序号不连续

分数排序leetcode178题 【不分组排序 】

select score,dense_rank() over(order by score desc) as 'rank'
from Scores

部门工资最高员工leetcode184题【分组排序】

select
Department,
Employee,
Salary
from
#----------将下面看作一个表----------
(select
b.name as Department,
a.name as Employee,
Salary,
rank() over(partition by departmentID order by salary desc) as salary_rank
from Employee a
join Department b
on a.departmentID = b.id) t
#----------用dense_rank()效果一样------------
where
salary_rank=1

窗口函数之-滑动窗口

实战演练:

select product,year_month,gmv,avg(gmv) over (partition by department, product order by year_month rows 2 preceding) as avg_gmv
from product

输出结果:

滚动求从上架到本月平均GMV?

select product,year_month,gmv,avg(gmv) over (partition by department, product order by year_month) as avg_gmv
from product

等价与:

select product,year_month,gmv,avg(gmv) over (partition by department, product order by year_month rows unbounded preceding) as avg_gmv
from product


注意:若需要求组内所有数据的平均:

select product,year_month,gmv,avg(gmv) over (partition by department, product) as avg_gmv
from product

窗口函数之-前后函数

应用:求同比增长、环比增长

  • lead(expression,n):返回当前行的后n行 => shift(-n) 数据超前n阶,与之对齐的就是后n行的数据
  • lag(expression,n):返回当前行的前n行=> shift(n)数据滞后n阶,与之对齐的就是前n行的数据

参数解析:
expression:作用的字段
n:阶数

select product,year_month,department,gmv,lag(gmv,1) over (partition by department, product order by year_month) as lag_gmv,cast(gmv as double) / lag(gmv,1) over (partition by department, product order by year_month) - 1 as growth_rate
from product

简化写法:

select product,year_month,department,gmv,lag(gmv,1) over w as lag_gmv,cast(gmv as double) / lag(gmv,1) over w - 1 as growth_rate
from product
WINDOW w as (partition by department, product order by year_month)

注意:cast(gmv as double)是将gmv转化为double类型。

问题:
日期不连续怎么办?
可以通过join万年历解决。

窗口函数求top 10%

  • percent_rank():公式 =(分组内当前的rank值-1)/(分组内总行数-1)
  • cume_dist():公式 =(分组内当前的rank值 )/( 分组内总行数)

对求解出的结果做限制result<=0.1即可得到前10%

  • ntile(n)
    功能:(相当于排序后分桶 / 百分位分桶)
    将排序分区划分特定数量的组;对应每一行,ntile(n)函数返回一个桶号,表示当前行所属的组。

求top10%:去ntile(n)中的n=10分桶后得到组号为1的即为前10%。

MYSQL开窗函数详解相关推荐

  1. Hive SQL开窗函数详解

    Hive 开窗函数 group by 是分组函数,一组出来一个数据 over() 开窗,针对每一条数据,都有一个独立的组 mk 3 jk 3 mk 3 select orderdate,cost,su ...

  2. mysql自定义函数详解

    1. 函数简介 mysql 5.0开始支持函数,函数是存在数据库中的一段sql集合,调用函数可以减少很多工作量, 减少数据在数据库和应用服务器上的传输,对于提高数据处理的效率.参数类型为in类型,函数 ...

  3. mysql capi函数详解_技术分享|MySQLCAPI参数MYSQL_OPT_READ_TIMEOUT的一些行为分析

    作者:戴岳兵 MYSQL_OPT_READ_TIMEOUT 是 MySQL c api 客户端中用来设置读取超时时间的参数.在 MySQL 的官方文档中,该参数的描述是这样的: MYSQL_OPT_R ...

  4. mysql capi函数详解_CAPI函数描述(A-F)

    25.2.3.1. mysql_affected_rows() my_ulonglong mysql_affected_rows(MYSQL *mysql) 描述 返回上次UPDATE更改的行数,上次 ...

  5. mysql capi函数详解_CAPI函数描述(G-N)

    25.2.3.26. mysql_get_character_set_info() void mysql_get_character_set_info(MYSQL *mysql, MY_CHARSET ...

  6. 【数据库】Navicat编写MySQL自定义函数详解

    小白最近迷上了MySQL,由于工作中大部分用HIVE,很少用到MySQL,但是后来发现MySQL可以处理递归等可循环的功能,所以,就安装了一个本地的MySQL进行学习,以下是小白对自定义函数的尝试. ...

  7. MySQL TRUNCATE 函数详解

    TRUNCATE(X,D) X 表示需要处理的数字,D 表示需要截取的位数.如果 D 为零,则返回的数字不含小数.D 也可以是负数,这样会把整数的部分置零. 示例如下: mysql> SELEC ...

  8. mysql时间函数详解

    1. 从时间中解析出年月日时间:date_format() 函数解析:date_format() 有两个参数,一个是date, 另一个是format:原理是将时间(date),转化成我们想要的格式(f ...

  9. Mysql CASE函数 详解

    CASE函数格式如下: CASE expr WHEN v1 THEN r1 [WHEN v2 THEN r2][ELSE rn] END 该函数表示,如果expr值等于某个vn,可以是等于v1或v2- ...

最新文章

  1. 计算机视觉开源库OpenCV之平滑、模糊和滤波
  2. numpy学习(2):数组创建方式
  3. XCode4.2 SVN设置
  4. [转载] Python一行代码实现1到100之和
  5. c++冒泡排序_python+C、C++混合编程的应用
  6. cuda_error_launch_failed: unspecified launch failure
  7. Win10正式版激活方法有哪些?如何激活Win10?
  8. Matlab画图线型、符号及颜色汇总
  9. android模拟器登录qq,手机 上来 个自动 Appium+Python3+夜神安卓模拟器 实现QQ自动登录...
  10. linux7找回删除的文件,centos7 rm -rf 删除文件的找回
  11. css规则中区块block,听晴空讲Drupal主题——第六章 主题中的CSS(10)
  12. 机械臂D-H参数法分析
  13. 我不 大冰2017新书pdf免费下载
  14. 博弈论中的MinMax搜索算法
  15. BSP-充电名词解释
  16. oracle补位函数 不足位数补0
  17. Android底部导航栏切换页面填坑
  18. UINavigation导航栏和UITabbar布局和样式
  19. poi中word中表格跨列合并以及不兼容wps问题,java下 linux下word转pdf 问题解决
  20. 理解控制变量、内生变量、外生变量、工具变量

热门文章

  1. 业务系统中的Word文档如何转成pdf
  2. 缺省(默认)VLAN
  3. 查询域名MX、A、DNS、txt、cname记录是否生效
  4. Spring中的设计模式之Handler模式(一)
  5. 如何组装一台自己最满意的电脑
  6. VUE定时器(页面定时刷新)
  7. 取余最长路 51Nod - 1624
  8. nginx常用的日志配置
  9. MAC重装Catania 10.15.5操作系统,附带下载地址。
  10. PerformanceCounter 基本介绍