SQL 窗口函数指南:深入解析窗口函数的神奇之处

文章介绍了SQL中的窗口函数,包括ROW_NUMBER(),RANK(),DENSE_RANK()等排名函数,以及NTILE()分位数函数,SUM(),AVG(),COUNT()等窗口聚合函数,还有FIRST_VALUE(),LAST_VALUE(),LEAD(),LAG(),PERCENT_RANK(),CUME_DIST()等其他功能强大的窗口函数。这些函数使数据分析和处理变得更高效,无需复杂子查询即可实现深入的数据洞察。
摘要由CSDN通过智能技术生成

引言

在这篇文章里,我们将揭开SQL世界的一大秘密——窗口函数!它像一把神奇的钥匙,让你在数据中开启新的视角。你不仅能轻松排名、统计、计算,还能实现数据滑窗和分组操作。无需复杂的子查询,窗口函数助你事半功倍!快跟我一起探索这个强大而有趣的功能,让你的SQL技能更上一层楼!

什么是窗口函数?

在SQL中,窗口函数是一组用于执行分析和计算的特殊函数。它们能够让你在不改变查询结果的情况下,对结果集中的行进行排序、分组和计算,从而获得更深入的数据分析。

窗口函数语法

窗口函数语法表格
函数功能语法
ROW_NUMBER()对结果集中的行进行编号

ROW_NUMBER() OVER(ORDER BY

column1[ASC/DESC])

RANK()

根据排序列对结果集中的行进行排名

RANK() OVER(ORDER BY column1 [ASC/DESC])

DENSE_RANK()根据排序列对结果集中的行进行排名

DENSE_RANK() OVER(ORDER BY column1

[ASC/DESC])

NTILE()将结果集划分为指定数量的桶NTILE(n) OVER(ORDER BY column1[ASC/DESC])
SUM()计算指定列的累计和

SUM(cloumn1) OVER(PARTITION BY column2

ORDER BY column3)

AVG()计算指定列的累计和

AVG(column1) OVER(PARTITION BY column2

ORDER BY column3)

COUNT()计算指定列的行数

COUNT(column1) OVER(PARTITION BY

column2 ORDER BY column3)

FIRST_VALUE()获取分组中第一行的指定列的值

FIRST_VALUE(column1) OVER(PARTITION BY

column2 ORDER BY column3)

LAST_VALUE()获取分组中最后一行的指定列的值

LAST_VALUE(column1) OVER(PARTITION BY

column2 ORDER BY column3)

LEAD()获取指定列下一行的值

LEAD(column1,offset,default) OVER(PARTITION

BY column2 ORDER BY column3)

LAG()获取指定列上一行的值

LAG(column1,offset,default) OVER(PARTITION

BY column2 ORDER BY column3)

PERCENT_RANK()计算指定列值的百分位排名

PERCENT_RANK() OVER(ORDER BY column1

[ASC/DESC])

CUME_DIST()计算指定列值的累积分布

CUME_DIST() OVER(ORDER BY column1

[ASC/DESC])

窗口函数的妙用

数据表如下:

students表

idnameage
1Alice20
2Bob22
3Carol19

scores表

student_idcoursescore
1Math85
1English78
1Science92
2Math90
2English88
2Science80
3Math76
3English85
3Science78
排名函数(Ranking Functions)

在排名函数组中,有三个常见的函数:ROW_NUMBER()RANK()DENSE_RANK()。这些函数用于对结果集中的行进行排名和排序。

1.ROW_NUMBER()函数

ROW_NUMBER()函数为每一行分配一个唯一的编号,无视重复值。它在排序后的结果集中对每一行进行标记,以便唯一标识该行在排序结果中的位置

SELECT id, name, ROW_NUMBER() OVER (ORDER BY age) AS row_number
FROM students;

运行结果

idnamerow_number
3Carol1
1Alice2
2Bob3
2.RANK()函数

RANK()函数根据排序列对结果集中的行进行排名,并可以处理并列排名。如果有多个行具有相同的排序值,则它们将被分配相同的排名,而下一个排名将会跳过相应的行数。

SELECT id, name, RANK() OVER (ORDER BY score DESC) AS rank
FROM scores;

运行结果

idnamerank
1Science1
2Math2
3English3
3.DENSE_RANK()函数

DENSE_RANK()函数与RANK()函数类似,也是根据排序列对结果集中的行进行排名。不同之处在于,DENSE_RANK()函数处理并列排名时不会跳过相应的行数,而是连续分配排名。

SELECT id, name, DENSE_RANK() OVER (ORDER BY score DESC) AS dense_rank
FROM scores;

运行结果

idnamedense_rank
1Science1
2Math2
3English3
分位数函数(Quantile Functions)

在分位数函数组中,有一个常见的函数:NTILE()。这个函数将结果集划分为指定数量的桶,每个桶内的行数尽量平均。

4.NTILE()函数

NTILE()函数将结果集划分为指定数量的桶,每个桶内的行数尽量平均。该函数将结果集中的行分成n个部分,每个部分包含大致相同数量的行,除非不能完全平均分配。

SELECT id, name, score, NTILE(3) OVER (ORDER BY score DESC) AS ntile
FROM scores;

运行结果

idnamescorentile
1Science921
2Math901
3English881
窗口聚合函数(Window Aggregate Functions)

在窗口聚合函数组中,有三个常见的函数:SUM()AVG()COUNT()。这些函数通过窗口来计算聚合值,而不是在整个结果集上进行计算。

5. SUM()函数

SUM()函数用于计算指定列的累计和。

SELECT s.id, s.name, sc.score,
       SUM(sc.score) OVER (PARTITION BY s.id) AS total_score
FROM students s
JOIN scores sc ON s.id = sc.student_id;

运行结果

idnametotal_score
1Alice255
2Bob258
3Carol239
6. AVG()函数

AVG()函数用于计算指定列的平均值。

SELECT s.id, s.name,
       AVG(sc.score) AS avg_score
FROM students s
JOIN scores sc ON s.id = sc.student_id
GROUP BY s.id, s.name;

运行结果

idnameavg_score
1Alice85.0
2Bob86.0
3Carol19.666
7. COUNT()函数

COUNT()函数用于计算指定列的行数。

SELECT s.id, s.name,
       COUNT(sc.score) AS num_courses
FROM students s
JOIN scores sc ON s.id = sc.student_id
GROUP BY s.id, s.name;

运行结果

idnamenum_courses
1Alice3
2Bob3
3Carol3
其他窗口函数

在其他窗口函数组中,有一些常见的函数,比如FIRST_VALUE()LAST_VALUE()LEAD()LAG()PERCENT_RANK()CUME_DIST()。这些函数在数据分析中非常有用。

8. FIRST_VALUE()函数

FIRST_VALUE()函数用于获取窗口中指定列的第一个值。

SELECT DISTINCT s.id, s.name,
       FIRST_VALUE(sc.score) OVER (PARTITION BY s.id, s.name ORDER BY sc.score) AS first_score
FROM students s
JOIN scores sc ON s.id = sc.student_id;

运行结果

idnamefirst_score
1Alice78
2Bob80
3Carol76
9. LAST_VALUE()函数

LAST_VALUE()函数用于获取窗口中指定列的最后一个值。

SELECT DISTINCT s.id, s.name,
       LAST_VALUE(sc.score) OVER (PARTITION BY s.id, s.name ORDER BY sc.score
                                ROWS BETWEEN UNBOUNDED preceding AND UNBOUNDED following) AS last_score
FROM students s
JOIN scores sc ON s.id = sc.student_id;

运行结果

idnamelast_score
1Alice92
2Bob80
3Carol78

10. LEAD()函数

LEAD()函数用于在窗口中获取指定列的后续行的值。

SELECT s.id, s.name, sc.course, sc.score,
       LEAD(sc.score) OVER (PARTITION BY s.id ORDER BY sc.course) AS next_score
FROM students s
JOIN scores sc ON s.id = sc.student_id;

运行结果

 11. LAG()函数

 LAG()函数用于获取窗口中指定列的前面行的值。它可以用来获取当前行前的任意行的值。

SELECT DISTINCT s.id, s.name, sc.course,
       LAG(sc.score) OVER (PARTITION BY s.id ORDER BY sc.course) AS previous_score
FROM students s
JOIN scores sc ON s.id = sc.student_id;

运行结果

idnamecourseprevious_score
1AliceMathNULL
1AliceEnglish85
1AliceScience78
2BobMathNULL
2BobEnglish90
2BobScience88
3CarolMathNULL
3CarolEnglish76
3CarolScience85

12. PERCENT_RANK()函数

PERCENT_RANK()函数用于计算每行相对于窗口的百分比排名值。它返回一个介于0和1之间的值,表示当前行在窗口中的百分比排名。

SELECT DISTINCT s.id, s.name, sc.course,
       PERCENT_RANK() OVER (PARTITION BY s.id ORDER BY sc.score) AS percent_rank_value
FROM students s
JOIN scores sc ON s.id = sc.student_id;

运行结果

idnamecoursepercent_rank_value
1AliceEnglish0.0
1AliceMath0.5
1AliceScience1.0
2BobEnglish0.0
2BobMath0.5
2BobScience1.0
3CarolEnglish0.0
3CarolMath0.5
3CarolScience1.0
13. CUME_DIST()函数

CUME_DIST()函数用于计算每行相对于窗口的累积分布值。它返回一个介于0和1之间的值,表示当前行在窗口中的累积分布百分比

SELECT DISTINCT s.id, s.name, sc.course,
       CUME_DIST() OVER (PARTITION BY s.id ORDER BY sc.score) AS cumulative_distribution
FROM students s
JOIN scores sc ON s.id = sc.student_id;

运行结果

idnamecoursecumulative_distribution
1AliceEnglish0.6667
1AliceScience1.0
1AliceMath0.3333
2BobEnglish0.6667
2BobScience1.0
2BobMath0.3333
3CarolEnglish0.6667
3CarolScience1.0
3CarolMath0.3333

结论

窗口函数为SQL查询提供了更加灵活和强大的功能。通过对结果集中的行进行排序、分组和计算,我们能够轻松实现复杂的数据分析和处理任务。希望这篇文章能够帮助你深入理解窗口函数的神奇之处,并在你的SQL学习之旅中探索更多可能性!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值