Click here to view and discuss this page in DocCommentXchange. In the future, you will be sent there automatically.

SQL Anywhere 11.0.1 (中文) » SQL Anywhere 服务器 - SQL 的用法 » 查询和修改数据 » OLAP 支持 » 窗口函数

 

窗口定义:内置与 WINDOW 子句

定义窗口的方法有三种:

  • 内置(在窗口函数的 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 窗口函数的计算。查询会按如下方式进行:

  1. 根据值 ProductID 分区(分组)输入行。

  2. 在每个分区内,根据 ShipDate 的值对行进行排序。

  3. 对于分区中的每一行,通过由各分区中(经过排序的)第一行直到当前行并包括当前行所组成的滑动窗口,使用 SUM 函数对 Quantity 中的值进行求值。

WINDOW 子句定义

上述查询的另一种结构是,使用 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 子句定义相结合

可以内置一部分窗口定义,然后在 WINDOW 子句中定义剩余部分。例如:

AVG() OVER ( windowA
             ORDER BY expression )...
...
WINDOW windowA AS ( PARTITION BY expression )

使用此方式分隔窗口定义时有以下限制:

  • 不能在窗口函数语法中使用 PARTITION BY 子句。

  • 可以在窗口函数语法或 WINDOW 子句中使用 ORDER BY 子句,但不能在二者中同时使用。

  • 不能在 WINDOW 子句中包括 RANGE 或 ROWS 子句。

另请参见