SQL总结-开窗函数
一 . 开窗函数
分组函数
语法结构:select col1,分析函数(col2) from table group by col1
开窗函数
语法结构:函数名(col2)over(partition by ool1 order by col3)
分组与开窗的区别
分组函数每组只返回一行,而开窗函数每组返回多行。如下:
分组查询
select visit_id, count(session_id) ct from event group by visit_id
![SQL总结-开窗函数](https://img.it610.com/image/info10/d67ea068d8154782a4a6872d2194573f.jpg)
文章图片
image 开窗查询
select visit_id,count(session_id) over(partition by visit_id) ct from event
![SQL总结-开窗函数](https://img.it610.com/image/info10/8704c923a42046f09b2deca078e770cc.jpg)
文章图片
image 对比可以发现,visit_id为00009e20-e3ec-4340-bf44-484b523fafbc时,用分组查询,ct只返回一行结果:8,而开窗查询visit_id的8条记录,都返回了,并且这八条记录的ct都为8。
二 . rows between关键字含义 PRECEDING:往前
FOLLOWING:往后
CURRENT ROW:当前行
UNBOUNDED:无边界,UNBOUNDED PRECEDING 表示从最前面的起点开始, UNBOUNDED FOLLOWING:表示到最后面的终点
举例如下:
![SQL总结-开窗函数](https://img.it610.com/image/info10/dbd967352ecd4caf888b623aecc20d82.png)
文章图片
image 三 . 常见分析函数总结
【SQL总结-开窗函数】测试数据
![SQL总结-开窗函数](https://img.it610.com/image/info10/fc8429cc4ab94c238d0432709e1c3004.jpg)
文章图片
image 1)sum求和函数 加order by时
select
cookieid,
createtime,
pv,
sum(pv) over(partition by cookieid order by createtime) as pv1
from event
![SQL总结-开窗函数](https://img.it610.com/image/info10/40834c1e251e4ad981b05a0371fcc26f.jpg)
文章图片
image 不加order by时
select
cookieid,
createtime,
pv,
sum(pv) over(partition by cookieid) as pv1
from event
![SQL总结-开窗函数](https://img.it610.com/image/info10/c0afa6ac111943cab51feb7d717e679f.jpg)
文章图片
image 对比可以发现,sum函数加了order by之后,不仅会对createtime排序,而且求的和是从起点到当前行的求和,而不是整个分区(分组)的求和。而不加order by,是对整个分组(分片)求和注:max()函数无论有没有order by 都是计算整个分区的最大值
2)几个排序函数 排序函数:row_number() 、rank() 、dense_rank() 、ntile() ,其区别如下:
(1) row_number() over():对相等的值不进行区分,相等的值对应的排名相同,序号从1到n连续。
(2)rank() over():相等的值排名相同,但若有相等的值,则序号从1到n不连续。如果有两个人都排在第3名,则没有第4名。
(3)dense_rank() over():对相等的值排名相同,但序号从1到n连续。如果有两个人都排在第一名,则排在第2名(假设仅有1个第二名)的人是第3个人。
(4) ntile( n ) over():可以看作是把有序的数据集合平均分配到指定的数量n的桶中,将桶号分配给每一行,排序对应的数字为桶号。如果不能平均分配,则较小桶号的桶分配额外的行,并且各个桶中能放的数据条数最多相差1。学生成绩表同上,查询语句如下:
select
id,
stu_name,
course_name,
grades,
row_number() over(order by grades) as row_num,
rank() over(order by grades) as rank,
dense_rank() over(order by grades) as dense_rank,
ntile(5) over(order by grades) as ntile
from students_grades
查询结果如下:
![SQL总结-开窗函数](https://img.it610.com/image/info10/877a5644289048d5ac7f84fd7a814724.jpg)
文章图片
image 3)lag和leag函数 lag(col,n,default) 用于统计窗口内往前第n行值,default表示默认值,意思是如果往前第n行的值null时,则返回默认值,如果不指定,则返回null。
SELECT
cookieid,
createtime,pv,
ROW_NUMBER() OVER(PARTITION BY cookieid ORDER BY createtime) AS rn,
LAG(createtime,1,'1970-01-01') OVER(PARTITION BY cookieid ORDER BY createtime) AS lag1,
LAG(createtime,2) OVER(PARTITION BY cookieid ORDER BY createtime) AS lag2
FROM event;
![SQL总结-开窗函数](https://img.it610.com/image/info10/ccdc6642656445808481277f1addde6b.jpg)
文章图片
image ps:leag(col,n,default) 用于统计窗口内往下第n行值
4)first_value和last_value函数 first_value返回分组内排序后,截止到当前行,第一个值
SELECT
cookieid,
createtime,
pv,
ROW_NUMBER() OVER(PARTITION BY cookieid ORDER BY createtime) AS rn,
FIRST_VALUE(pv) OVER(PARTITION BY cookieid ORDER BY createtime) AS first
FROM event
![SQL总结-开窗函数](https://img.it610.com/image/info10/fe8b7760c3d04863aa392e906f0dd826.jpg)
文章图片
image ps:last_value和first_value相反,取最后一个值
参考文档:
1)Hive开窗函数整理
https://blog.csdn.net/Abysscarry/article/details/81408265?utm_medium=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase
2)数据分析(SQL)常见面试题(一):开窗函数
https://www.douban.com/group/topic/155112949/
最后欢迎关注微信公众号
![SQL总结-开窗函数](https://img.it610.com/image/info10/e7d1b4fb96cb457a80439648663f47fd.png)
文章图片
image.png
推荐阅读
- 7.9号工作总结~司硕
- 最有效的时间管理工具(赢效率手册和总结笔记)
- 数据库总结语句
- 周总结|周总结 感悟
- 周总结43
- 参加【21天写作挑战赛】,第七期第14天,挑战感受小总结
- py连接mysql
- 2019-01-18Mysql中主机名的问题
- 第二阶段day1总结
- MySql数据库备份与恢复