定义窗口的方法有三种:
内置(在窗口函数的 OVER 子句中)
在 WINDOW 子句中
部分内置,部分在 WINDOW 子句中
然而,有些方法存在限制,如以下各节中所述。
窗口定义可以放在窗口函数的 OVER 子句中。这称为以内置 方式定义窗口。
例如,以下语句在 SQL Anywhere 示例数据库中查询 2001 年七月和八月发运的所有产品,以及截至发运日期的累计发运量。窗口采用内置方式定义。
SELECT p.ID, p.Description, s.Quantity, s.ShipDate, SUM( s.Quantity ) OVER ( PARTITION BY s.ProductID ORDER BY s.ShipDate ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) AS Cumulative_qty FROM SalesOrderItems s JOIN Products p ON ( s.ProductID = p.ID ) WHERE s.ShipDate BETWEEN '2001-07-01' AND '2001-08-31' ORDER BY p.ID; |
此查询会返回以下结果:
ID | Description | Quantity | ShipDate | Cumulative_qty | |
---|---|---|---|---|---|
1 | 301 | V-neck | 24 | 2001-07-16 | 24 |
2 | 302 | Crew Neck | 60 | 2001-07-02 | 60 |
3 | 302 | Crew Neck | 36 | 2001-07-13 | 96 |
4 | 400 | Cotton Cap | 48 | 2001-07-05 | 48 |
5 | 400 | Cotton Cap | 24 | 2001-07-19 | 72 |
6 | 401 | Wool Cap | 48 | 2001-07-09 | 48 |
7 | 500 | Cloth Visor | 12 | 2001-07-22 | 12 |
8 | 501 | Plastic Visor | 60 | 2001-07-07 | 60 |
9 | 501 | Plastic Visor | 12 | 2001-07-12 | 72 |
10 | 501 | Plastic Visor | 12 | 2001-07-22 | 84 |
11 | 601 | Zipped Sweatshirt | 60 | 2001-07-19 | 60 |
12 | 700 | Cotton Shorts | 24 | 2001-07-26 | 24 |
在此示例中,要在连接两个表和应用查询的 WHERE 子句之后,才执行 SUM 窗口函数的计算。查询会按如下方式进行:
根据值 ProductID 分区(分组)输入行。
在每个分区内,根据 ShipDate 的值对行进行排序。
对于分区中的每一行,通过由各分区中(经过排序的)第一行直到当前行并包括当前行所组成的滑动窗口,使用 SUM 函数对 Quantity 中的值进行求值。
上述查询的另一种结构是,使用 WINDOW 子句在使用窗口的函数中单独指定窗口,然后在各函数的 OVER 子句内引用窗口。
在此示例中,WINDOW 子句创建名为 Cumulative、按 ProductID 对数据分区并按 ShipDate 进行排序的窗口。SUM 函数在其 OVER 子句中引用窗口,并使用 ROWS 子句定义窗口大小。
SELECT p.ID, p.Description, s.Quantity, s.ShipDate, SUM( s.Quantity ) OVER ( Cumulative ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) AS cumulative_qty FROM SalesOrderItems s JOIN Products p ON ( s.ProductID = p.ID ) WHERE s.ShipDate BETWEEN '2001-07-01' AND '2001-08-31' WINDOW Cumulative AS ( PARTITION BY s.ProductID ORDER BY s.ShipDate ) ORDER BY p.ID; |
当使用 WINDOW 子句语法时,以下限制将适用:
如果指定 PARTITION BY 子句,则必须将其置于 WINDOW 子句内。
如果指定 ROWS 或 RANGE 子句,则必须将其置于引用函数的 OVER 子句中。
如果为窗口指定 ORDER BY 子句,可将该子句置于 WINDOW 子句中,或者置于引用函数的 OVER 子句中,但不能同时置于二者之中。
WINDOW 子句必须位于 SELECT 语句的 ORDER BY 子句之前。
可以内置一部分窗口定义,然后在 WINDOW 子句中定义剩余部分。例如:
AVG() OVER ( windowA ORDER BY expression )... ... WINDOW windowA AS ( PARTITION BY expression ) |
使用此方式分隔窗口定义时有以下限制:
不能在窗口函数语法中使用 PARTITION BY 子句。
可以在窗口函数语法或 WINDOW 子句中使用 ORDER BY 子句,但不能在二者中同时使用。
不能在 WINDOW 子句中包括 RANGE 或 ROWS 子句。
Copyright © 2009, iAnywhere Solutions, Inc. - SQL Anywhere 11.0.1 |