OVER 子句定义在其上执行 OLAP window 表达式的结果集。
如果 OVER 子句为空,则您必须还包括空的圆括号。
OLAP window 分区是由查询返回的行的子集。通过定义该 window 的 OVER 子句的 PARTITION BY 规范中的一个或多个列表达式定义每一分区。数据库服务器将指定的 OLAP window 函数应用于每一 window 分区中的所有行。如果在 OVER 子句中未定义分区,则将 window 函数应用于该查询的结果集中的每行。
数据库服务器根据 window ORDER 子句中的排序键(或多个排序键)对每一 window 分区中的行排序。如果您未指定升序(ASC)或降序(DESC)顺序,则缺省值为 ASC。如果未指定 ORDER 子句,则按照检索到的行的顺序排列符合条件的行。
window Frame 子句返回每一 window 分区中的行的子集,称为聚集组。由特定数目的行或值的范围来定义 window frame。
AVG(price) OVER (ORDER BY year, day ROWS BETWEEN 6 PRECEDING AND CURRENT ROW)
COUNT(*) OVER (ORDER BY ship_date RANGE BETWEEN 2 PRECEDING AND 2 FOLLOWING)
在基于行和基于值的这两种情况下,在此 window frame 的内容上计算 OLAP 函数,而不是在整个分区的固定的内容上计算。window frame 不需要包含当前行。例如,下列规范定义仅包含当前行之前的行的 window frame:
ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING
ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
下列查询返回按一年的季度的销售额,以及按季度的销售额的累积总和。
SELECT sales, SUM(sales) OVER (ORDER BY quarter) FROM sales WHERE year = 2012 sales (sum) 120 120 135 255 127 382 153 535
第四季度的销售额的总和等于所有四个季度中的销售额。
由于该查询未包括 window frame 子句,因此,SUM 函数如通过 FROM 子句指定的那样,在整个结果集上操作。
下列查询按照团队分区并按照分数排序来返回运动员。在每一分区内,对该运动员以及与前面的运动员的分数求平均值:
select team, player, points, AVG(points) OVER(PARTITION BY team ORDER BY points ROWS 1 PRECEDING AND CURRENT ROW) AS olap_avg FROM points; TEAM PLAYER POINTS OLAP_AVG A Singh 7 7.00000000000 A Smith 14 10.50000000000 B Osaka 8 8.00000000000 B Ricci 12 10.00000000000 B Baxter 18 15.00000000000 C Chun 13 13.00000000000 D Kwan 9 9.00000000000 D Tran 16 12.50000000000
下列查询按照团队分区并按照年龄排序,返回运动员。在每一分区内,对每一运动员以及最多大 9 岁的运动员的分数求平均值:
SELECT player, age, team, points, AVG(points) OVER(PARTITION BY team ORDER BY age RANGE BETWEEN CURRENT ROW AND 9 FOLLOWING) AS olap_avg FROM points_age; PLAYER AGE TEAM POINTS OLAP_AVG Singh 25 A 7 10.50000000000 Smith 26 A 14 14.00000000000 Baxter 27 B 18 13.00000000000 Osaka 35 B 8 10.00000000000 Ricci 40 B 12 12.00000000000 Chun 21 C 13 13.00000000000 Kwan 22 D 9 12.50000000000 Tran 31 D 16 16.00000000000
在分区 A 中,Singh 的平均值包括 Smith 的分数,因为 Smith 比 Singh 大一岁。Smith 的平均值不包括来自 Singh 的分数,因为 Singh 比 Smith 年轻。
在分区 B 中,Baxter 的平均值包括 Osaka 的分数,其比 Baxter 大 8 岁,但不包括 Ricci,其比 Baxter 大 13 岁。
在分区 D 中,Kwan 的平均值包括 Tran 的分数,因为 Tran 比 Kwan 大 9 岁。
下列查询计算分区中前面两行的分数的平均值:
SELECT player, age, team, points, AVG(points) OVER(PARTITION BY team ORDER BY age ROWS BETWEEN 2 PRECEDING AND 1 PRECEDING) AS olap_avg FROM points_age; PLAYER AGE TEAM POINTS OLAP_AVG Singh 25 A 7 NULL Smith 26 A 14 7.00000000000 Baxter 27 B 18 NULL Osaka 35 B 8 18.00000000000 Ricci 40 B 12 13.00000000000 Chun 21 C 13 NULL Kwan 22 D 9 NULL Tran 31 D 16 9.00000000000
在分区 B 中,Ricci 的平均值是基于 Baxter 和 Osaka 的分数合计:(18 + 8 = 26)/2 = 13。当当前行没有前面的行用于计算时,结果为 NULL。