关于开窗函数的使用 over (partition by order by)

本文深入探讨了数据库中的窗口函数,如Oracle和MySQL 8.0+支持的PARTITION BY和ORDER BY功能。这些函数允许对数据进行分组和排序,实现复杂的数据分析。例如,LAG()函数用于获取前一个分组内的值,ROW_NUMBER()用于为数据行编号,SUM()和AVG()等聚合函数可在分组内计算累计和平均值。此外,还介绍了rank()和dense_rank()在处理并列情况下的差异。通过理解并应用这些函数,可以提升数据库查询的效率和灵活性。

开窗函数功能很强大

Oracle数据库是支持这种写法的,mysql的话要8版本或以上才支持

PARTITION 中文是分割的意思,ORDER 是排序的意思,把一组数据按照制定的字段进行分割成各种组,然后组内按照某个字段排序

简而言之就是

分组后对组内数据排序

写法:

select id,name,class_id,score,lag(score,1,0)

over (partition by class_id order by score desc) before_score from t_student;

mysql8.0之前写法:

SELECT
    c.id,
    c.NAME,
    c.class_id,
    c.score,
    c.before_score
FROM
    (
SELECT
IF ( @id = a.class_id, @lagname := @score, @lagname := '' ) AS before_score,
    @id := a.class_id AS aclass_id,
    @score := a.score AS aafter_score,
    a.*
FROM
    ( SELECT * FROM t_student ORDER BY class_id, score DESC ) a,
    ( SELECT @lagname := NULL, @id := 0, @score := NULL ) b
    ) c;

或者,采用子查询,先排序,再分组,找到最值元素

扩展

over (partition by order by)

还可以有这种写法

over (order by),整个数据就是一个大块

配合ROW_NUMBER() 函数可以做到组内数据从1开始编号

ROW_NUMBER()  over (partition by class_id order by score desc)   no       对数据的编号

与OVER(PARTITION BY... ORDER BY...)匹配使用的函数

row_number() over()、rank() over()和dense_rank() over()

在上面的例子里,使用ROW_NUMBER()可以对数据编号,但是有一个问题,例子中的MI_ID是不可以重复的,如果在可以重复的情况下,就有并列的情况,这样就无法取出并列的数据,只能取单一排序的数据。所以这里可以换成 rank() over()和dense_rank() over()来进行编号:(rank() over()和dense_rank() over()的区别如图)

sum() over(),first_value() over()和last_value() over()的使用

sum() over()分组求和

first_value() over()求分组第一条

last_value() over()求分组最后一条

其中用row_number() over()取编号第一条的也可以实现first_value() over()的效果

常用的分析函数如下所列:

row_number() over(partition by ... order by ...)
rank() over(partition by ... order by ...)
dense_rank() over(partition by ... order by ...)
count() over(partition by ... order by ...)
max() over(partition by ... order by ...)
min() over(partition by ... order by ...)
sum() over(partition by ... order by ...)
avg() over(partition by ... order by ...)
first_value() over(partition by ... order by ...)
last_value() over(partition by ... order by ...)
lag() over(partition by ... order by ...)
lead() over(partition by ... order by ...)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值