MySql教程

mysql高阶-窗口函数-分析函数

本文主要是介绍mysql高阶-窗口函数-分析函数,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

窗口函数-分析函数

  • 1 lead(x,y,z) 函数:领先,找行号更大的数据 返回当前行后面的值
  • 2 lag(x,y,z) 函数:落后,找行号更小的数据 返回当前行之前的值
  • 3 FIRST_VALUE(expr) 返回指定列的第一个值
  • 4 LAST_VALUE(expr) 返回指定列的最后一个值
  • 5 (巨重要)nth_value(x,n) 函数返回X列,按指定顺讯的第n个值
  • 小结

1 lead(x,y,z) 函数:领先,找行号更大的数据 返回当前行后面的值

LEAD(x,y,z) 函数:   领先,找行号更大的数据   返回当前行后面的值
										x: 列名  y:偏移量(如果y =2,则说明要以当前行为基准,向后移动两行为返回值)
										z: 默认值时null ,如果传入z ,则默认值是z
LEAD(x) over()    1 最后一列没有下一列结果显示null
									2 lead(x) x的值 与排序的列可以不同


栗子:
统计id 为1的网站,每天访问的人数以及下一天访问的人数- 返回字段:`day`日期,`users`访问人数,`lead` 下
一天访问人数
 							
SELECT
		day,
		users,
		LEAD(users) over(order by day) as `下一天访问日期人数`
FROM
statistics
WHERE website_id = 1;
实际用途!!!!!!!!!!!!!!!! 
从业务逻辑来看 这可以很容易的告诉我们有关网站的很多信息
① 正数: 上升期
②负数: 找到下滑原因

使用LEAD()函数计算增量
SELECT 
		day,
		clicks,
		LEAD(clicks) over(order by day) as `下一天的点击量`,
		clicks - LEAD(clicks) over(order by day)  as `点击差值`	
from 
statistics
WHERE website_id =2;


需求:统计id为1的网站,每日收入,后一天收入,以及每日收入的环比。
SELECT
		revenue,
		LEAD(revenue) over(ORDER BY day) as `下一天收入`,
		LEAD(revenue) over(ORDER BY day) -revenue as `环比`		
FROM
statistics
WHERE
website_id = 1;

需求:统计id为2的网站,在2016年5月1日到5月14日之间,每天的用户访问数量以及7天后的用户访问数量
需要注意,最后7行最后一列会返回NULL,因为最后7行没有7日后的数据。

SELECT 
		day,
		users,
		lead(users,7) over(ORDER BY day) as 	`七天后的用户访问量`
FROM
statistics
WHERE website_id = 2 and day BETWEEN '2016-05-01' AND '2016-05-14';

2 lag(x,y,z) 函数:落后,找行号更小的数据 返回当前行之前的值

lag(x) 函数         落后,找行号更小的数据  返回当前行之前的值
										x: 列名  y:偏移量(如果y =2,则说明要以当前行为基准,向前移动两行为返回值)
										z: 默认值时null ,如果传入z ,则默认值是z
lag(x) over()     1 最后一列没有下一列结果显示null
									2 lag(x) x的值 与排序的列可以不同


需求:统计id为3的网站每天的点击数量,前一天的点击数量
SELECT 
	day,
	clicks,
	LAG(clicks,1,-1) over(ORDER BY day) as `前一天的连击量`
FROM
statistics
WHERE website_id =3;


需求:统计id = 3的网站每日广告收入以及三天前的广告收入

SELECT
	day,
	revenue,
	LAG(revenue,3,-1) over(ORDER BY day) as 	`三天前的广告收入`
FROM
statistics
WHERE website_id =3;


转化率定义:转化率= 点击次数 clicks / 展示次数 impressions * 100
需求:统计id = 1的网站,5月15日至5月31日,每天点击次数 clicks,展示次数 impressions,转化率
(conversion)和前一天的转化率(previous_conversion)
SELECT
	day,
	clicks,
	impressions,
	clicks / impressions * 100 as `转化率` ,
	LAG(clicks) over(ORDER BY day) /LAG(impressions) over(ORDER BY day) * 100 as `前一天转化率`
FROM
statistics
where website_id = 1 and day BETWEEN '2016-05-15' AND '2016-05-31' ;

3 FIRST_VALUE(expr) 返回指定列的第一个值

需求:统计id为2的网站每天用户访问情况,以及最少用户访问人数。
SELECT
	day,
	users,
	FIRST_VALUE(users) over(ORDER BY	users ) as `最少用户访问人数`
from 
statistics
WHERE website_id = 2;

需求:统计id = 3 的网站收入情况,返回日期,收入,和第一天的收入
SELECT
	day,
	revenue,
	FIRST_VALUE(revenue) over(order by day ) as `第一天的收入`
FROM
statistics
WHERE website_id =3;

统计id为1的网站的广告展示情况,返回每日日期,广告展示次数,以及访问用户最多的一天广告展示的次数
SELECT
	day,
	impressions,
	FIRST_VALUE(impressions) over(order by impressions desc) as `最高展示次数`
FROM
statistics
WHERE website_id = 1;

4 LAST_VALUE(expr) 返回指定列的最后一个值

注意:使用last_value()时候的时候.要注意范围的限制.
要加上 rows BETWEEN unbounded preceding AND unbounded following

返回最近开始营业的网站,我们运行一下
SELECT
	name,
	opened,
	LAST_VALUE(opened) over(ORDER BY opened  rows 
												BETWEEN unbounded preceding AND unbounded following)
	
from
website;


需求:统计id为1的网站,每日的访问用户数,最后一天的访问用户数,每日用户数与最后一天用户数的差值
SELECT
	day,
	users,
	LAST_VALUE(users) over(ORDER BY day rows BETWEEN unbounded  preceding AND unbounded following) as `最后一天访问用户数`,
	users - LAST_VALUE(users) over(ORDER BY day rows BETWEEN unbounded  preceding AND unbounded following) as 		`diff`
FROM
statistics
WHERE
website_id = 1;

5 (巨重要)nth_value(x,n) 函数返回X列,按指定顺讯的第n个值

!!!巨他妈重要partition by order by topn问题
nth_value(x,n) 函数返回X列,按指定顺讯的第n个值
排序的时候加上desc调整排序的顺序,配合nth_value(x,n) 在某些场景下更方便
NTH_VALUE 通常要求把window frame修改成 ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING

统计id为2的网站的收入情况,在5月15和5月31日之间,每天的收入,以及这半个月内的第三高的日收入金额
SELECT
	day,
	revenue,
	NTH_VALUE(revenue,3) over(ORDER BY revenue desc rows BETWEEN unbounded preceding AND  unbounded following) as `半个月内第三高的收入金额`
FROM
statistics
WHERE website_id = 2 and day BETWEEN '2016-05-15' AND '2016-05-31';

统计5月14日的不同网站收入情况,返回如下字段:
网站website_id, 当日收入revenue
所有网站当日最高收入highest_revenue
所有网站当日最少收入lowest_revenue
SELECT
	website_id,
	revenue,
	NTH_VALUE(revenue,1) over(ORDER BY revenue desc) as `highest_revenue`,
	NTH_VALUE(revenue,1) over(ORDER BY revenue asc)  as `lowest_revenue`
FROM
statistics
WHERE day = '2016-05-14';


需求:统计id为1的网站的点击量,返回如下字段
- 日期 day, 点击量 clicks ,5月点击量的中位数
- 提示:5月一共31天,将点击量按顺序排列,第16位点击量即为中位数    
SELECT
	day,
	clicks,
	NTH_VALUE(clicks,16) over(order by clicks rows BETWEEN unbounded preceding AND unbounded following) as `点击中位数`
FROM
statistics
WHERE website_id = 1;

p140 
需求:统计id为3的网站每天点击的情况,返回如下字段
- 日期`day`,点击量`clicks`,最高点击量和当天点击量的比例`ratio`(用整数表示)

SELECT
	day,
	clicks,
	ROUND(	clicks / LAST_VALUE(clicks) over(ORDER BY clicks desc rows BETWEEN unbounded preceding and unbounded following)) as `ratio`
from
statistics
WHERE website_id = 3
ORDER BY day;

小结

  • LEAD(x) 和 LAG(x) 分别返回传入的列x对于当前行的下一行/前一行的值
  • LEAD(x,y) 和 LAG(x,y) 分别返回传入的列x对于当前行的后y行/前y行的值
  • FIRST_VALUE(x) 和 LAST_VALUE(x) 分别返回列x 的第一个值/最后一个值
  • NTH_VALUE(x,n) 返回 x 列的 第n个值
  • LAST_VALUE 和 NTH_VALUE 通常要求把window frame修改成 ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
这篇关于mysql高阶-窗口函数-分析函数的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!