

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# WINDOW 子句 (滑动窗口)
<a name="sql-reference-window-clause"></a>

滑动窗口式查询的 `WINDOW` 子句指定一些行，将跨与当前行相关的一组行针对这些行计算分析函数。这些聚合函数生成一个输出行，该行按每个输入行的一个或多个列中的键进行聚合。查询中的 `WINDOW` 子句指定流中按时间范围间隔或行数分区的记录，以及由 `PARTITION BY` 子句指定的一组额外的可选列。您可以定义指定的或内联的窗口规范，这些规范可在分析函数和流式 `JOIN` 子句中使用。有关分析函数的更多信息，请参阅[分析函数](sql-reference-analytic-functions.md)。

对 `OVER` 子句中指定的每个列执行滑动窗口查询中的聚合函数。`OVER` 子句可以引用指定的窗口规范，也可以作为数据泵的 `SELECT` 语句的一部分内联。以下示例说明如何使用 `OVER` 子句引用指定的窗口规范并在 `SELECT` 语句中内联使用。

## 语法
<a name="w2aac20c15c30b7"></a>

```
[WINDOW window_name AS 
(
	{PARTITION BY partition_name 
		RANGE INTERVAL 'interval' {SECOND | MINUTE | HOUR} PRECEDING | 
		ROWS number PRECEDING
, …}
)
```

## OVER 子句
<a name="w2aac20c15c30b9"></a>

以下示例说明如何使用 `OVER` 子句引用指定的窗口规范。

**示例 1：引用指定的窗口规范的 OVER**

以下示例显示的是引用了名为 W1 的窗口规范的聚合函数。在此示例中，基于 `W1` 窗口规范所指定的记录集来计算平均价格。要了解有关如何将 OVER 子句与窗口规范结合使用的更多信息，请参阅[示例](#sql-reference-window-clause-examples)。

```
AVG(price) OVER W1 AS avg_price 
```

**示例 2：引用内联窗口规范的 OVER**

 以下示例显示的是引用了内联窗口规范的聚合函数。在此示例中，基于每个输入行与内联窗口规范来计算平均价格。要了解有关如何将 OVER 子句与窗口规范结合使用的更多信息，请参阅[示例](#sql-reference-window-clause-examples)。

```
AVG(price) OVER (
    PARTITION BY ticker_symbol
    RANGE INTERVAL '1' HOUR PRECEDING) AS avg_price
```

有关聚合函数和 OVER 子句的更多信息，请参阅[聚合函数](sql-reference-aggregate-functions.md)。

## 参数
<a name="w2aac20c15c30c11"></a>

*window-name*

指定可从 OVER 子句或后续窗口定义引用的唯一名称。此名称在分析函数和流式 `JOIN` 子句中使用。有关分析函数的更多信息，请参阅[分析函数](sql-reference-analytic-functions.md)。

AS

为 `WINDOW` 子句定义指定的窗口规范。

PARTITION BY *partition-name*

将行划分到共享相同值的组中。在对行进行划分后，窗口函数将计算当前行所在划分中的所有行。

RANGE INTERVAL *'interval'* \$1SECOND \$1 MINUTE \$1 HOUR\$1 PRECEDING

根据时间范围间隔指定窗口边界。窗口函数将计算具有与当前行相同的时间间隔的所有行。

ROWS *number* PRECEDING

根据行数指定窗口边界。窗口函数将计算在相同行数内的所有行。

## 示例
<a name="sql-reference-window-clause-examples"></a>

### 示例数据集
<a name="w2aac20c15c30c13b3"></a>

以下示例基于样本股票数据集，后者是 *Amazon Kinesis Analytics 开发人员指南*中的[入门](https://docs.aws.amazon.com/kinesisanalytics/latest/dev/get-started-exercise.html)的一部分。要运行每个示例，您需要一个具有样本股票代码输入流的 Amazon Kinesis Analytics 应用程序。要了解如何创建 Analytics 应用程序和配置样本股票代码输入流，请参阅 *Amazon Kinesis Analytics 开发人员指南*中的[入门](https://docs.aws.amazon.com/kinesisanalytics/latest/dev/get-started-exercise.html)。有关其他示例，请参阅[滑动窗口](https://docs.aws.amazon.com/kinesisanalytics/latest/dev/sliding-window-concepts.html)。

具有以下架构的示例股票数据集。

```
(ticker_symbol  VARCHAR(4),
sector          VARCHAR(16),
change          REAL,
price           REAL)
```

### 示例 1：引用了指定的窗口规范的基于时间的滑动窗口
<a name="w2aac20c15c30c13b5"></a>

此示例定义了一个指定的窗口规范，其分区边界为当前行前一分钟。数据泵的 `OVER` 语句的 `SELECT` 子句引用指定的窗口规范。

```
WINDOW W1 AS (
    PARTITION BY ticker_symbol 
    RANGE INTERVAL '1' MINUTE PRECEDING);
```

要运行此示例，请创建股票示例应用程序，并运行和保存以下 SQL 代码。

```
CREATE OR REPLACE STREAM "DESTINATION_SQL_STREAM" (
    ticker_symbol VARCHAR(4), 
    min_price     DOUBLE, 
    max_price     DOUBLE, 
    avg_price     DOUBLE);
CREATE OR REPLACE PUMP "STREAM_PUMP" AS 
    INSERT INTO "DESTINATION_SQL_STREAM"
    SELECT STREAM ticker_symbol,
        MIN(price) OVER W1 AS min_price,
        MAX(price) OVER W1 AS max_price,
        AVG(price) OVER W1 AS avg_price
    FROM "SOURCE_SQL_STREAM_001"
    WINDOW W1 AS (
        PARTITION BY ticker_symbol 
        RANGE INTERVAL '1' MINUTE PRECEDING);
```

上一示例输出的流与以下内容类似。

![\[Table showing stock data with columns for rowtime, ticker symbol, and price information.\]](http://docs.aws.amazon.com/zh_cn/kinesisanalytics/latest/sqlref/images/sql-reference-analytic-functions-example-1.png)


### 示例 2：引用了指定的窗口规范的基于行的滑动窗口
<a name="w2aac20c15c30c13b7"></a>

此示例定义了一个指定的窗口规范，其分区边界为当前行前两到十行。数据泵的 `OVER` 语句的 `SELECT` 子句引用指定的窗口规范。

```
 WINDOW
    last2rows AS (PARTITION BY ticker_symbol ROWS 2 PRECEDING),
    last10rows AS (PARTITION BY ticker_symbol ROWS 10 PRECEDING);
```

要运行此示例，请创建股票示例应用程序，并运行和保存以下 SQL 代码。

```
CREATE OR REPLACE STREAM "DESTINATION_SQL_STREAM" (
    ticker_symbol      VARCHAR(4), 
    price              DOUBLE, 
    avg_last2rows      DOUBLE, 
    avg_Last10rows     DOUBLE);
CREATE OR REPLACE PUMP "myPump" AS INSERT INTO "DESTINATION_SQL_STREAM"
SELECT STREAM ticker_symbol, 
    price, 
    AVG(price) OVER last2rows, 
    AVG(price) OVER last10rows
FROM SOURCE_SQL_STREAM_001
WINDOW
    last2rows AS (PARTITION BY ticker_symbol ROWS 2 PRECEDING),
    last10rows AS (PARTITION BY ticker_symbol ROWS 10 PRECEDING);
```

上一示例输出的流与以下内容类似。

![\[Table showing stock ticker symbols, prices, and average values for multiple rows.\]](http://docs.aws.amazon.com/zh_cn/kinesisanalytics/latest/sqlref/images/sql-reference-analytic-functions-example-2.png)


### 示例 3：带内联窗口规范的基于时间的滑动窗口
<a name="w2aac20c15c30c13b9"></a>

此示例定义了一个内联窗口规范，其分区边界为当前行前一分钟。数据泵的 `OVER` 语句的 `SELECT` 子句使用内联窗口规范。

要运行此示例，请创建股票示例应用程序，并运行和保存以下 SQL 代码。

```
CREATE OR REPLACE STREAM "DESTINATION_SQL_STREAM" (
    ticker_symbol VARCHAR(4),
    price         DOUBLE,
    avg_price     DOUBLE);
CREATE OR REPLACE PUMP "STREAM_PUMP" AS 
    INSERT INTO "DESTINATION_SQL_STREAM"
    SELECT STREAM ticker_symbol, price, 
        AVG(Price) OVER (
            PARTITION BY ticker_symbol
            RANGE INTERVAL '1' HOUR PRECEDING) AS avg_price
    FROM "SOURCE_SQL_STREAM_001"
```

上一示例输出的流与以下内容类似。

![\[Table showing stock data with columns for timestamp, ticker symbol, price, and average price.\]](http://docs.aws.amazon.com/zh_cn/kinesisanalytics/latest/sqlref/images/sql-reference-analytic-functions-example-3.png)


## 使用说明
<a name="w2aac20c15c30c15"></a>

### 
<a name="w2aac20c15c30c15b2"></a>

对于 WINDOW 子句和终端节点，Amazon Kinesis Analytics SQL 在某个范围内遵循窗口的 SQL-2008 标准。

要包括 1 小时的终端节点，您可以使用以下窗口语法。

```
WINDOW HOUR AS (RANGE INTERVAL '1' HOUR PRECEDING) 
```

要排除上一个小时的终端节点，您可以使用以下窗口语法。

```
WINDOW HOUR AS (RANGE INTERVAL '59:59.999' MINUTE TO SECOND(3) PRECEDING);
```

有关更多信息，请参阅 [允许和不允许的窗口规范](sql-reference-allowed-disallowed-window.md)。

## 相关主题
<a name="w2aac20c15c30c17"></a>
+ 《Kinesis 开发人员指南》中的[滑动窗口](https://docs.aws.amazon.com/kinesisanalytics/latest/dev/sliding-window-concepts.html)
+ [聚合函数](sql-reference-aggregate-functions.md)
+ [SELECT 语句](sql-reference-select.md)
+ [CREATE STREAM](sql-reference-create-stream.md) statement
+ [CREATE PUMP](sql-reference-create-pump.md) statement

# 允许和不允许的窗口规范
<a name="sql-reference-allowed-disallowed-window"></a>

Amazon Kinesis Data Analytics 支持几乎所有以当前行结尾的窗口。

您不能定义无限窗口、负数大小的窗口，也不能在窗口规范中使用负整数。目前不支持偏移窗口。
+ 无限窗口是指没有边界的窗口。通常指向未来，对于流来说是无限的。例如，不支持“ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING”，因为在流上下文中，此类查询不会生成结果，因为流会随着新数据的到达而不断扩展。不支持 UNBOUNDED FOLLOWING 的所有用法。
+ 负数窗口。例如，“ROWS BETWEEN 0 PRECEDING AND 4 PRECEDING”是一个大小为负数的窗口，因此是非法的。在这种情况下，您可以改用“ROWS BETWEEN 4 PRECEDING AND 0 PRECEDING”。
+ 偏移窗口是指不以 CURRENT ROW 结尾的窗口。当前版本不支持此类窗口。例如，不支持“ROWS BETWEEN UNBOUNDED PRECEDING AND 4 FOLLOWING”。（窗口跨越 CURRENT ROW，而不是从其开始或结束。）
+ 用负整数定义的窗口。例如，“ROWS BETWEEN -4 PRECEDING AND CURRENT ROW”无效，因为不允许使用负整数。

此外，... 0 PRECEDING (and ... 0 FOLLOWING) 不能用于窗口式聚合，但可以使用同义词 CURRENT ROW。

对于窗口式聚合，允许使用分区式窗口，但不得存在 ORDER BY。

对于窗口式联接，不允许使用分区式窗口，但是如果按其中一个输入的 ROWTIME 列排序，则可以存在 ORDER BY。

# 窗口示例
<a name="sql-reference-window-examples"></a>

以下示例显示了样本输入数据集、多个窗口的定义以及这些窗口在 10:00 之后的不同时间（在本示例中，是数据开始到达的时间）的内容。

窗口的定义如下：

```
SELECT STREAM
  ticker,
  sum(amount) OVER lastHour,
  count(*) OVER lastHour
  sum(amount) OVER lastThree
FROM Trades
WINDOW
  lastHour AS (RANGE INTERVAL '1' HOUR PRECEDING),
  lastThree AS (ROWS 3 PRECEDING),
  lastZeroRows AS (ROWS CURRENT ROW),
  lastZeroSeconds AS (RANGE CURRENT ROW),
  lastTwoSameTicker AS (PARTITION BY ticker ROWS 2 PRECEDING),
  lastHourSameTicker AS (PARTITION BY ticker RANGE INTERVAL '1' HOUR PRECEDING)
```

## 第一个示例：基于时间的窗口与基于行的窗口
<a name="sql-reference-window-examples-example-1"></a>

如下图右侧所示，基于时间的 lastHour 窗口包含不同数量的行，因为窗口成员资格是由时间范围定义的。

![\[Time-based window examples showing ROWTIME, ticker, and amount columns with varying row counts.\]](http://docs.aws.amazon.com/zh_cn/kinesisanalytics/latest/sqlref/images/window-examples.png)


## 包含行的窗口的示例
<a name="sql-reference-window-examples-example-rows"></a>

基于行的 lastThree 窗口通常包含四行：前三行和当前行。但是，对于行 10:10 IBM，它只包含两行，因为 10:00 之前没有数据。

基于行的窗口可以包含多行，这些行的 ROWTIME 值相同，尽管它们到达的时间不同（挂钟时间）。此类行在基于行的窗口中的顺序取决于其到达时间；实际上，行的到达时间可以决定哪个窗口包含该行。

例如，图 1 中间的 lastThree 窗口显示了 YHOO 交易在 ROWTIME 为 11:15 时到达（及其之前的最后三笔交易）。但是，此窗口不包括下一笔交易，即 IBM，其 ROWTIME 也是 11:15，但必须晚于 YHOO 交易到达。此 11:15 IBM 交易包含在“下一个”窗口中，其前身 11:15 YHOO 交易也是如此。

第二个示例：基于行和基于时间的零宽度窗口

图 2：零宽度窗口的示例显示了宽度为零的基于行和基于时间的窗口。基于行的窗口仅 lastZeroRows 包含当前行，因此始终只包含一行。请注意，ROWS CURRENT ROW 等同于 ROWS 0 PRECEDING。

基于时间的窗口 lastZeroSeconds 包含具有相同时间戳的所有行，其中可能有几行。请注意，RANGE CURRENT ROW 等同于 RANGE INTERVAL '0' SECOND PRECEDING。

![\[Examples of zero-width windows showing ROWTIME, ticker, and amount columns with time-based data.\]](http://docs.aws.amazon.com/zh_cn/kinesisanalytics/latest/sqlref/images/window-examples2.png)


## 第三个示例：分区适用于基于行和基于时间的窗口
<a name="sql-reference-window-examples-THIRDEXAMPLE"></a>

图 3 显示的窗口与图 1 中的窗口类似，但带有 PARTITION BY 子句。对于基于时间的窗口 lastTwoSame Ticker 和基于行的窗口 lastHourSame Ticker，该窗口包含符合窗口条件且与股票行情列值相同的行。注意：分区是在窗口之前计算的。

![\[Table showing partitioned windows with ROWTIME, ticker, and amount columns for stock data.\]](http://docs.aws.amazon.com/zh_cn/kinesisanalytics/latest/sqlref/images/window-examples3.png)
