SQL基本功 II

窗口函数:

在讲什么是窗口函数之前,先来举几个在写SQL时,经常遇到的一些场景。

💻场景1:

现在数据库中有一张用户交易表order,其中有userid(用户ID)、amount(消费金额)、paytime(支付时间),请写出对应的SQL语句,查出每个用户第一单的消费金额。

💻场景2:

数据库中有一张销售业绩表,其中有销售员id,部门名称,销售金额。要取出每个部门销售金额Top10的员工,作为优秀员工。

其实本质上,场景1和场景2的内容是一样。

如果是查询每个用户最大金额、最小金额,对于熟悉SQL的同学,应该比较清晰,直接group by就行。但这里多了一个条件,按照金额的时间取第一单、或者按照销售取top10,即不再是全局排序、统计。你该咋办呢?

对,解决这种SQL取数的问题,就需要用到窗口函数。


PARTITION BY表示将数据先按 part_list 进行分区

ORDER BY 表示将各个分区内的数据按 order_list 进行排序

1.排序函数

几个不同排序函数的一些差异,可以根据不同的业务场景选择合适的函数:

RANK(): 生成数据项在分组中的排名,排名相等会在名次中留下空位。比如会出现1、2、2、4、4、6、7

ROW_NUMBER(): 从1开始,按照顺序,生成分组内记录的序列,row_number()的值不会存在重复,当排序的值相同时,按照表中记录的顺序进行排列。结果只会是1、2、3、4、5、6、7

DENSE_RANK(): 生成数据项在分组中的排名,排名相等会在名次中不会留下空位,比如会出现1、2、2、3、3、4、5这种

eg.给流量表按照用户的访问时间加上每个用户的访问次序:

代码块

SELECT

userid,

createtime,

pv,

rank() over(partition BY userid order by pv DESC) AS rn1,

dense_rank() over(partition BY userid order by pv DESC) AS rn2,

row_number() over(partition BY userid order by pv DESC) AS rn3

FROM tb_visit;

eg.取各二级类目下sku的订单金额总和前10的数据

代码块

select *,

row_number() over(partition by cate2_name order by amount desc) rank_secd

from tbname

where  rank_secd<=10


2.聚合函数

有以下示例:

代码块

SELECT *,

sum(col2) over (partition by col1 order by col2) as current_sum,

avg(col2) over (partition by col1 order by col2) as current_avg,

count(col2) over (partition by col1 order by col2) as current_count,

max(col2) over (partition by col1 order by col2) as current_max,

min(col2) over (partition by col1 order bycol2) as current_min

FROM tbname;


3.取值函数

FIRST_VALUE():取分组内排序后,截止到当前行,第一个值

LAST_VALUE():取分组内排序后,截止到当前行,最后一个值

LAG():LAG(col,n,DEFAULT) 用于统计窗口内往上第n行值

LEAD():与LAG相反 LEAD(col,n,DEFAULT) 用于统计窗口内往下第n行值

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容