MySQL 8.0 新增SQL语法对窗口函数和CTE的支持(2)

  dense_rank()的出现是为了解决rank()编号存在的问题的,
  rank()编号的时候存在跳号的问题,如果有两个并列第1,那么下一个名次的编号就是3,结果就是没有编号为2的数据。
  如果不想跳号,可以使用dense_rank()替代。

  

MySQL 8.0 新增SQL语法对窗口函数和CTE的支持

avg,sum等聚合函数在窗口函数中的的增强

  可以在聚合函数中使用窗口功能,比如sum(amount)over(partition by user_no order by create_date) as sum_amont,达到一个累积计算sum的功能
  这种需求在没有窗口函数的情况下,用纯sql写起来,也够蛋疼的了,就不举例了。

  

MySQL 8.0 新增SQL语法对窗口函数和CTE的支持

NTILE(N) 将数据按照某些排序分成N组

  举个简单的例子,按照分数线的倒序排列,将学生成绩分成上中下3组,可以得到哪个程序数据上中下三个组中哪一部分,就可以使用NTILE(3) 来实现。这种需求倒是用的不是非常多。
  如下还是使用上面的表,按照时间将user_no = 'u0002'的订单按照时间的纬度,划分为3组,看每一行数据数据哪一组。

  

MySQL 8.0 新增SQL语法对窗口函数和CTE的支持

first_value(column_name) and last_value(column_name)

  first_value和last_value基本上见名知意了,就是取某一组数据,按照某种方式排序的,最早的和最新的某一个字段的值。
  看结果体会一下。

MySQL 8.0 新增SQL语法对窗口函数和CTE的支持

nth_value(column_name,n)

  从排序的第n行还是返回nth_value字段中的值,这个函数用的不多,要表达的这种逻辑,说实话,很难用语言表达出来,看个例子体会一下就行。

  n = 3

MySQL 8.0 新增SQL语法对窗口函数和CTE的支持

  n = 4

MySQL 8.0 新增SQL语法对窗口函数和CTE的支持

cume_dist

  在某种排序条件下,小于等于当前行值的行数/总行数,得到的是数据在某一个纬度的分布百分比情况。
  比如如下示例
  第1行数据的日期(create_date)是2018-01-05 00:00:00,小于等于2018-01-05 00:00:00的数据是1行,计算方式是:1/6 = 0.166666666
  第2行数据的日期(create_date)是2018-01-06 00:00:00,小于等于2018-01-06 00:00:00的数据是2行,计算方式是:2/6 = 0.333333333
  依次类推
  第4行数据的日期(create_date)是2018-01-16 00:00:00,小于等于2018-01-16 00:00:00的数据是4行,计算方式是:4/6 = 0.6666666666
  第一行数据的0.6666666666 意味着,小于第四行日期(create_date)的数据占了符合条件数据的66.66666666666%  

MySQL 8.0 新增SQL语法对窗口函数和CTE的支持

percent_rank()

  同样是数据分布的计算方式,只不过算法变成了:当前RANK值-1/总行数-1 。
  具体算法不细说,这个实际中用的也不多。

MySQL 8.0 新增SQL语法对窗口函数和CTE的支持

lag以及lead

  lag(column,n)获取当前数据行按照某种排序规则的上n行数据的某个字段,lead(column,n)获取当前数据行按照某种排序规则的下n行数据的某个字段,
  确实很拗口。
  举个实际例子,按照时间排序,获取当前订单的上一笔订单发生时间和下一笔订单发生时间,(可以计算订单的时间上的间隔度或者说买买买的频繁程度)

select order_id,
        user_no,
        amount,
        create_date,
      lag(create_date,1) over (partition by user_no order by create_date asc) 'last_transaction_time',
      lead(create_date,1) over (partition by user_no order by create_date asc) 'next_transaction_time'from order_info ;

  

MySQL 8.0 新增SQL语法对窗口函数和CTE的支持

CTE 公用表表达式

  CTE有两种用法,非递归的CTE和递归的CTE。
  非递归的CTE可以用来增加代码的可读性,增加逻辑的结构化表达。
  平时我们比较痛恨一句sql几十行甚至上上百行,根本不知道其要表达什么,难以理解,对于这种SQL,可以使用CTE分段解决,
  比如逻辑块A做成一个CTE,逻辑块B做成一个CTE,然后在逻辑块A和逻辑块B的基础上继续进行查询,这样与直接一句代码实现整个查询,逻辑上就变得相对清晰直观。
  举个简单的例子,当然这里也不足以说明问题,比如还是第一个需求,查询每个用户的最新一条订单
  第一步是对用户的订单按照时间排序编号,做成一个CTE,第二步对上面的CTE查询,取行号等于1的数据。

MySQL 8.0 新增SQL语法对窗口函数和CTE的支持

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/14f00a867dc719aafd82f8d657d82107.html