第十四章 SQL窗口函数概述(一)

2022-01-05  本文已影响0人  Cache技术分享

第十四章 SQL窗口函数概述(一)

指定用于计算聚合和排名的每行“窗口框架”的函数。

窗口函数和聚合函数

在应用WHEREGROUP byHAVING子句之后,窗口函数对SELECT查询选择的行进行操作。

窗口函数将一组行中的一个(或多个)字段的值组合在一起,并在结果集中为生成的列中的每一行返回一个值。

虽然窗口函数与聚合函数类似,因为它们将多行结果组合在一起,但它们与聚合函数的不同之处在于,它们本身并不组合行。

窗函数的语法

窗口函数被指定为SELECT查询中的选择项。
窗口函数也可以在SELECT查询的ORDER BY子句中指定。

窗口函数执行与由PARTITION by子句、ORDER by子句和ROWS子句指定的逐行窗口相关的任务,并为每一行返回一个值。
这三个子句都是可选的,但是如果指定了,必须按照以下语法中的顺序指定:

window-function() OVER (
                      [ PARTITION BY partfield ]
                      [ ORDER BY orderfield ]
                      [ ROWS framestart ] | [ ROWS BETWEEN framestart AND frameend ]
                      )

其中framestartframeend可以是:

UNBOUNDED PRECEDING |
offset PRECEDING |
CURRENT ROW |
UNBOUNDED FOLLOWING |
offset FOLLOWING

如果指定了一个PARTITION BY子句,行被分组在指定的窗口中,窗口函数创建一个新的结果集字段并为每一行分配一个值。
例如,PARTITION BY City将共享相同City字段值的所有行分组到同一个窗口中;
窗口函数根据这个分组分配行值。

ORDER BY按排序规则升序对窗口函数值进行排序。如果指定PARTITION BYORDER BY,则行将被分区为组,每个组的orderfield值将被排序,窗口函数将创建一个新的结果集字段并为每行赋值。如果在没有PARTITION BY子句的情况下指定ORDER BY子句,则所有选定的行将在单个窗口中分组、排序,然后赋值。例如,ORDER BY City根据City字段的值对所有行进行排序,然后Window函数按该顺序为每行赋值。

简单的例子

CityTable包含具有以下值的行:

Name City
Able New York
Betty Boston
Charlie Paris
Davis Boston
Eve Paris
Francis Paris
George London
Beatrix Paris

ROW_NUMBER()窗口函数根据指定的窗口为每一行分配一个唯一的连续整数。

SELECT Name,City,ROW_NUMBER() OVER (PARTITION BY City) FROM CityTable
Name City Window_3
Able New York 1
Betty Boston 1
Charlie Paris 1
Davis Boston 2
Eve Paris 2
Francis Paris 3
George London 1
Beatrix Paris 4
SELECT Name,City,ROW_NUMBER() OVER (ORDER BY City) FROM CityTable

本例将所有行视为单个分区。
它根据City值对行排序,并返回以下结果:

Name City Window_3
Able New York 4
Betty Boston 1
Charlie Paris 5
Davis Boston 2
Eve Paris 6
Francis Paris 7
George London 3
Beatrix Paris 8
SELECT Name,City,ROW_NUMBER() OVER (Partition BY City ORDER BY Name) FROM CityTable

这个例子根据City值对行进行分区,根据Name值对每个City分区排序,并返回以下结果:

Name City Window_3
Able New York 1
Betty Boston 1
Charlie Paris 2
Davis Boston 2
Eve Paris 3
Francis Paris 4
George London 1
Beatrix Paris 1

NULL

PARTITION BY子句将字段为NULL(没有分配值)的行作为分区组处理。
例如,ROW_NUMBER() OVER (Partition BY City)会将没有City值的行分配为顺序整数,就像它将顺序整数分配给City值为'Paris'的行一样。

ORDER BY子句将字段为NULL(没有分配值)的行按照在任何分配值(具有最低的排序值)之前的顺序处理。
例如,ROW_NUMBER() OVER (ORDER BY City)首先将顺序整数分配给没有City值的行,然后将顺序整数分配给排序顺序中具有City值的行。

ROWS子句将NULL(没有赋值)的字段视为值为零。
例如,SUM(Scores) OVER (ORDER BY Scores ROWS 1 above)/2将分配0.00给所有没有分数值的行((0 + 0)/2),并通过将0加到它然后除以2来处理第一个分数值。

支持的窗口函数

支持以下窗口函数:

SUM既可以用作聚合函数,也可以用作窗口函数。
SUM()支持ROWS子句。

下面的例子比较了这些窗口函数中ORDER by子句返回的值:

SELECT Name,City,ROW_NUMBER() OVER (ORDER BY City) AS RowNum,
  RANK() OVER (ORDER BY City) AS RankNum,
  PERCENT_RANK() OVER (ORDER BY City) AS RankPct
  FROM CityTable ORDER BY City

本例将所有行视为单个分区。
它根据City值对行排序,并返回以下结果:

Name City RowNum RankNum RankPct
Harriet   1 1 0
Betty Boston 2 2 .1111111111111111111
Davis Boston 3 2 .1111111111111111111
George London 4 4 .3333333333333333333
Able New York 5 5 .4444444444444444444
Charlie Paris 6 6 .5555555555555555555
Eve Paris 7 6 .5555555555555555555
Francis Paris 8 6 .5555555555555555555
Beatrix Paris 9 6 .5555555555555555555
Jackson Rome 10 10 1
上一篇下一篇

猜你喜欢

热点阅读