> ## Documentation Index
> Fetch the complete documentation index at: https://private-7c7dfe99-fix-nav-issues.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# avgState

> avgState 组合器使用示例

<div id="description">
  ## 描述
</div>

[`State`](/zh/reference/functions/aggregate-functions/combinators#-state) 组合器
可应用于 [`avg`](/zh/reference/functions/aggregate-functions/avg)
函数，以生成 `AggregateFunction(avg, T)` 类型的中间状态，其中
`T` 是平均值的指定类型。

<div id="example-usage">
  ## 示例用法
</div>

在本示例中，我们将介绍如何结合使用 `AggregateFunction` 类型与 `avgState` 函数来聚合网站流量数据。

首先为网站流量数据创建源表：

```sql theme={null}
CREATE TABLE raw_page_views
(
    page_id UInt32,
    page_name String,
    response_time_ms UInt32,  -- 页面响应时间（毫秒）
    viewed_at DateTime DEFAULT now()
)
ENGINE = MergeTree()
ORDER BY (page_id, viewed_at);
```

创建用于存储平均响应时间的聚合表。请注意，`avg` 无法使用 `SimpleAggregateFunction` 类型，因为它需要复杂状态 (包含求和值与计数值) 。因此，我们使用 `AggregateFunction` 类型：

```sql theme={null}
CREATE TABLE page_performance
(
    page_id UInt32,
    page_name String,
    avg_response_time AggregateFunction(avg, UInt32)  -- 存储 avg 计算所需的状态
)
ENGINE = AggregatingMergeTree()
ORDER BY page_id;
```

创建一个增量materialized view，作为插入触发器处理新数据，并将中间状态数据存储到上面定义的目标表中：

```sql theme={null}
CREATE MATERIALIZED VIEW page_performance_mv
TO page_performance
AS SELECT
    page_id,
    page_name,
    avgState(response_time_ms) AS avg_response_time  -- 使用 -State 组合器
FROM raw_page_views
GROUP BY page_id, page_name;
```

向源表插入一些初始数据，在磁盘上创建一个分片：

```sql theme={null}
INSERT INTO raw_page_views (page_id, page_name, response_time_ms) VALUES
    (1, 'Homepage', 120),
    (1, 'Homepage', 135),
    (2, 'Products', 95),
    (2, 'Products', 105),
    (3, 'About', 80),
    (3, 'About', 90);
```

插入更多数据以在磁盘上创建第二个分片：

```sql theme={null}
INSERT INTO raw_page_views (page_id, page_name, response_time_ms) VALUES
(1, 'Homepage', 150),
(2, 'Products', 110),
(3, 'About', 70),
(4, 'Contact', 60),
(4, 'Contact', 65);
```

检查目标表 `page_performance`：

```sql theme={null}
SELECT 
    page_id,
    page_name,
    avg_response_time,
    toTypeName(avg_response_time)
FROM page_performance
```

```response theme={null}
┌─page_id─┬─page_name─┬─avg_response_time─┬─toTypeName(avg_response_time)──┐
│       1 │ Homepage  │ �                 │ AggregateFunction(avg, UInt32) │
│       2 │ Products  │ �                 │ AggregateFunction(avg, UInt32) │
│       3 │ About     │ �                 │ AggregateFunction(avg, UInt32) │
│       1 │ Homepage  │ �                 │ AggregateFunction(avg, UInt32) │
│       2 │ Products  │ n                 │ AggregateFunction(avg, UInt32) │
│       3 │ About     │ F                 │ AggregateFunction(avg, UInt32) │
│       4 │ Contact   │ }                 │ AggregateFunction(avg, UInt32) │
└─────────┴───────────┴───────────────────┴────────────────────────────────┘
```

请注意，`avg_response_time` 列的类型为 `AggregateFunction(avg, UInt32)`，存储的是中间状态信息。另外请注意，`avg_response_time` 的行数据对我们而言没有实际意义，显示的是诸如 `\uFFFD, n, F, }` 之类的乱码字符。这是终端尝试将二进制数据以文本形式呈现的结果。根本原因在于，`AggregateFunction` 类型以二进制格式存储其状态，该格式针对高效存储与计算进行了优化，而非为人类可读性而设计。这一二进制状态包含了计算平均值所需的全部信息。

要使用它，请使用 `Merge` 组合器：

```sql theme={null}
SELECT
    page_id,
    page_name,
    avgMerge(avg_response_time) AS average_response_time_ms
FROM page_performance
GROUP BY page_id, page_name
ORDER BY page_id;
```

现在我们可以看到正确的平均值：

```response theme={null}
┌─page_id─┬─page_name─┬─average_response_time_ms─┐
│       1 │ Homepage  │                      135 │
│       2 │ Products  │       103.33333333333333 │
│       3 │ About     │                       80 │
│       4 │ Contact   │                     62.5 │
└─────────┴───────────┴──────────────────────────┘
```

<div id="see-also">
  ## 另请参见
</div>

* [`avg`](/zh/reference/functions/aggregate-functions/avg)
* [`State`](/zh/reference/functions/aggregate-functions/combinators#-state)
