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';
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' ;
需求:统计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;
注意:使用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;
!!!巨他妈重要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;