简而言之:
Over子句可用于选择非聚合值以及聚合值。
Partition BY、ORDER BY inside 和ROWS 或 RANGE是 OVER() by 子句的一部分。
partition by 用于对数据进行分区,然后执行这些窗口、聚合函数,如果我们没有 partition by,则将整个结果集视为单个分区。
OVER 子句可以与排名函数(Rank、Row_Number、Dense_Rank..)、聚合函数(如(AVG、Max、Min、SUM...等)和分析函数(如 First_Value、Last_Value 等)一起使用。
让我们看看 OVER 子句的基本语法
OVER (
[ <PARTITION BY clause> ]
[ <ORDER BY clause> ]
[ <ROW or RANGE clause> ]
)
PARTITION BY:用于对数据进行分区并对具有相同数据的组执行操作。
ORDER BY:用于定义Partitions中数据的逻辑顺序。当我们不指定 Partition 时,整个结果集被视为单个分区
:这可用于指定在执行操作时应该在分区中考虑哪些行。
举个例子:
这是我的数据集:
Id Name Gender Salary
----------- -------------------------------------------------- ---------- -----------
1 Mark Male 5000
2 John Male 4500
3 Pavan Male 5000
4 Pam Female 5500
5 Sara Female 4000
6 Aradhya Female 3500
7 Tom Male 5500
8 Mary Female 5000
9 Ben Male 6500
10 Jodi Female 7000
11 Tom Male 5500
12 Ron Male 5000
所以让我执行不同的场景,看看数据是如何受到影响的,我将从困难的语法变成简单的语法
Select *,SUM(salary) Over(order by salary RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) as sum_sal from employees
Id Name Gender Salary sum_sal
----------- -------------------------------------------------- ---------- ----------- -----------
6 Aradhya Female 3500 3500
5 Sara Female 4000 7500
2 John Male 4500 12000
3 Pavan Male 5000 32000
1 Mark Male 5000 32000
8 Mary Female 5000 32000
12 Ron Male 5000 32000
11 Tom Male 5500 48500
7 Tom Male 5500 48500
4 Pam Female 5500 48500
9 Ben Male 6500 55000
10 Jodi Female 7000 62000
只需观察 sum_sal 部分。在这里,我使用按薪水排序并使用"RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW"。在这种情况下,我们没有使用分区,因此整个数据将被视为一个分区,并且我们按薪水排序。这里重要的是UNBOUNDED PRECEDING 和 CURENT ROW。这意味着当我们计算总和时,每行从起始行到当前行。但是,如果我们看到薪水为 5000 且 name="Pavan" 的行,理想情况下它应该是 17000,而薪水 = 5000 和 name=Mark,它应该是 22000。但是当我们使用RANGE在这种情况下,如果它找到任何相似的元素,那么它将它们视为相同的逻辑组并对它们执行操作并将值分配给该组中的每个项目。这就是为什么我们的薪水 = 5000 具有相同值的原因。引擎上升到salary=5000 和Name=Ron 并计算总和,然后将其分配给所有salary=5000。
Select *,SUM(salary) Over(order by salary ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) as sum_sal from employees
Id Name Gender Salary sum_sal
----------- -------------------------------------------------- ---------- ----------- -----------
6 Aradhya Female 3500 3500
5 Sara Female 4000 7500
2 John Male 4500 12000
3 Pavan Male 5000 17000
1 Mark Male 5000 22000
8 Mary Female 5000 27000
12 Ron Male 5000 32000
11 Tom Male 5500 37500
7 Tom Male 5500 43000
4 Pam Female 5500 48500
9 Ben Male 6500 55000
10 Jodi Female 7000 62000
因此,与无界前行和当前行之间的行不同的是相同值的项目而不是将它们组合在一起,它计算从起始行到当前行的总和,并且它不会像RANGE那样对待具有相同值的项目
Select *,SUM(salary) Over(order by salary) as sum_sal from employees
Id Name Gender Salary sum_sal
----------- -------------------------------------------------- ---------- ----------- -----------
6 Aradhya Female 3500 3500
5 Sara Female 4000 7500
2 John Male 4500 12000
3 Pavan Male 5000 32000
1 Mark Male 5000 32000
8 Mary Female 5000 32000
12 Ron Male 5000 32000
11 Tom Male 5500 48500
7 Tom Male 5500 48500
4 Pam Female 5500 48500
9 Ben Male 6500 55000
10 Jodi Female 7000 62000
这些结果与
Select *, SUM(salary) Over(order by salary RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) as sum_sal from employees
这是因为Over(order by Salary)只是Over(order by Salary RANGE BETWEEN UNBOUNDED PRECEDING 和当前行)的一个捷径,
所以无论我们简单地指定Order by without ROWS 或 RANGE,它都采用RANGE BETWEEN UNBOUNDED PRECEDING 和当前行作为默认。
注意:这仅适用于实际接受 RANGE/ROW 的函数。例如,ROW_NUMBER 和少数其他人不接受 RANGE/ROW,在这种情况下,这不会出现在图片中。
到目前为止,我们看到带有 order by 的 Over 子句采用 Range/ROWS,语法看起来像这样RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
它实际上是从第一行计算到当前行。但是如果它想计算整个数据分区的值并为每一列(即从第一行到最后一行)计算值,该怎么办。这是查询
Select *,sum(salary) Over(order by salary ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) as sum_sal from employees
Id Name Gender Salary sum_sal
----------- -------------------------------------------------- ---------- ----------- -----------
1 Mark Male 5000 62000
2 John Male 4500 62000
3 Pavan Male 5000 62000
4 Pam Female 5500 62000
5 Sara Female 4000 62000
6 Aradhya Female 3500 62000
7 Tom Male 5500 62000
8 Mary Female 5000 62000
9 Ben Male 6500 62000
10 Jodi Female 7000 62000
11 Tom Male 5500 62000
12 Ron Male 5000 62000
我指定了UNBOUNDED FOLLOWING而不是 CURRENT ROW,它指示引擎计算直到每行分区的最后一条记录。
现在谈到空括号的 OVER() 是什么?
这只是Over(按薪水在无界前和无界之间的行排序)的捷径
在这里,我们间接指定将我的所有结果集视为单个分区,然后执行从每个分区的第一条记录到最后一条记录的计算。
Select *,Sum(salary) Over() as sum_sal from employees
Id Name Gender Salary sum_sal
----------- -------------------------------------------------- ---------- ----------- -----------
1 Mark Male 5000 62000
2 John Male 4500 62000
3 Pavan Male 5000 62000
4 Pam Female 5500 62000
5 Sara Female 4000 62000
6 Aradhya Female 3500 62000
7 Tom Male 5500 62000
8 Mary Female 5000 62000
9 Ben Male 6500 62000
10 Jodi Female 7000 62000
11 Tom Male 5500 62000
12 Ron Male 5000 62000
我确实为此制作了一个视频,如果您有兴趣,可以访问它。
https://www.youtube.com/watch?v=CvVenuVUqto&t=1177s
谢谢, Pavan Kumar Aryasomayajulu
HTTP://xyzcoder.github.io