标题SQL窗口函数之partition by

标题SQL窗口函数之partition by

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

partition by与group by都是对表中的某维度进行分组。不同的是partition by返回的是分组后的每一条记录,不改变表中数据行数,后续可以做排序、topN等操作;而 group by返回的是分组的聚合值,例如max、sum、avg等值。`


一、窗口函数

1.基本语法:

<窗口函数> over ( partition by<用于分组的列名> order by <用于排序的列名> desc) as "rank_col"

执行顺序为:
1、根据 <用于分组的列名> 进行分组操作(partition by),得到分组结果(中间表);
2、对结果的每个分组进行组内(desc降序)排序:order by <用于排序的列名>(中间表);
3、将窗口函数用于上述结果的每个分组(over):增加组内排序序号列"rank_col"。窗口函数包括rank(),dense_rank(),row_number()等。
以上过程生成了一个分组、组内排序、增加组内排序序号列的结果。

rank()函数:如果有并列名次的行,会占用下一个名次的位置。比如正常排名是1,2,3,4,但是现在前3名是并列的名次,所以结果是:1,1,1,4.
dense_rank()函数:如果有并列的名次,它不会占用下一个名次的位置,比如比如正常排名是1,2,3,4,但是现在前3名是并列的名次,所以结果是:1,1,1,2.
row_number()函数:不考虑并列的情况,比如前3名是并列的名次,排名是正常的1,2,3,4.

2.示例

[LC185]. 部门工资前三高的所有员工

公司的主管们感兴趣的是公司每个部门中谁赚的钱最多。一个部门的 高收入者 是指一个员工的工资在该部门的 不同 工资中 排名前三 。编写解决方案,找出每个部门中 收入高的员工 。
输出格式要求如下:
在这里插入图片描述
分析:
题目要求是找出 每个部门中 排名前三的员工(partition by 部门),且相同收入水平并列、不占用后续排序位置(dense_rank())。
写sql前,最好把过程先想清楚,把每个中间子表想清楚,把重要的中间子表可以查出来看看,最后再完善代码,且不要上来就搞代码。思路如下:

1、先把最核心的计算写出来

分组以及组内排序:

select *,
dense_rank() over(partition by departmentId order by salary desc) as rank_col
from Employee 

在这里插入图片描述
按分组排序输出了,且增加了排序列rank_col,但是没有限制前三。

2、从上面的结果中,取每组的前三

把上面的结果当作子表查询

select * from(
select *,
dense_rank() over(partition by departmentId order by salary desc) as rank_col
from Employee ) a
where a.rank_col <=3

在这里插入图片描述
到这里,核心的计算算是完成了,实现了 每个部门中排名前三,且相同收入水平并列、不占用后续排序位置的要求。下一步,要按照规定格式输出。

3、按要求格式输出

继续把上面的结果当作子表查询

select d.name Department, b.name Employee,b.salary Salary 
from 
(select * from(
select *,
dense_rank() over(partition by departmentId order by salary desc) as rank_col
from Employee ) a
where a.rank_col <=3) b
left join Department d on b.departmentId = d.id

在这里插入图片描述输出正确,测试通过。

4、sql优化

分组以及组内排序后,直接join,节省一个中间子表

select d.name Department, a.name Employee,a.salary Salary
from
(select *,
dense_rank() over(partition by departmentId order by salary desc) as "rank"
from Employee ) a
left join Department d on a.departmentId  = d.id
where a.rank <4

输出正确,测试通过。

  • 23
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Spark SQL中的窗口函数over partition by是一种用于对数据进行分组计算的函数。它可以将数据按照指定的列进行分组,并在每个分组内进行计算。这种函数在数据分析和处理中非常常见,可以帮助我们更方便地进行数据聚合和统计。 ### 回答2: Spark SQL窗口函数是一种强大的函数,可以对窗口内的数据进行分组聚合、排序、排名、分析计算等操作。在实际的数据处理过程中,常常会遇到需要对数据进行分组、聚合等操作的场景,这时候,窗口函数就可以发挥重要作用。 Over partition by是spark sql窗口函数中的一种非常强大的函数,能够对指定字段进行分组聚合。在使用over partition by时,需要定义一个窗口,即用来指定数据的分组方式。通常情况下,partition by子句用来指定需要分组的字段,over子句则用来执行数据计算的操作。 例如,如果需要计算一组数据不同时间点的总和,则可以使用over partition by函数来实现。首先,在select子句中指定需要计算的字段,然后使用over partition子句指定分组方式,最后使用sum函数计算总和。如下所示: ``` SELECT time,value,sum(value) over (partition by time) FROM table_name; ``` 上述示例中,partition by子句使用time字段进行分组,然后将value字段用于计算每个分组的总和。 除了上述示例中的聚合操作,Spark SQL中的over partition by函数还可以执行窗口排序、排名、累计计算、百分比计算等多种计算操作。例如,使用over partition by函数来实现窗口排序,则可以使用排列相关的函数,如rank、dense_rank、row_number等。 总结来说,Spark SQL中的over partition by函数是一种非常强大的窗口函数,可以在数据处理过程中实现复杂的分组、排序、排名、累计计算、百分比计算等多种计算操作。对于需要对数据进行多重分组、聚合分析的场景,使用over partition by函数可以非常方便地实现数据分析处理的任务。 ### 回答3: Spark SQL中的窗口函数over partition by是一种用于在查询结果集中处理数据的功能。窗口函数可以在数据中划分子集,执行聚合函数,计算行号等操作。这些操作与简单的分组聚合或排序不同,因为他们不会对查询结果进行分组,而是对子集进行操作,同时保留查询结果集的完整性。 over partition by语法可用于将查询结果集划分为多个分区,然后在每个分区上执行操作。对于每个分区,分配一个排名或数字,允许在对查询结果集进行其他处理之前,对子集进行排序或聚合操作。 over partition by语法的基本语法格式为: SELECT col1, col2, sum(col3) OVER (PARTITION BY col1) FROM table1 以上语句将查询结果集按照col1进行分区,并对每个分区进行col3的聚合操作,最后在每行返回结果集中的col1、col2、col3聚合总和。 over partition by语法中还可以使用其他聚合函数,如avg()、min()、max()等等。同时,还支持rank()、dense_rank()、row_number()、ntile()等其他更高级的分析函数。 over partition by的使用可以帮助我们更好的处理查询结果集中的数据。通过使用这个功能,我们可以轻松地执行各种分析操作,比如打造数据仪表盘、制定分析计划等等。当我们需要比单个分组细化分析数据时,over partition by语法就是非常有用的。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值