跳到主要内容
跳到主要内容

minSimpleState

描述

SimpleState 组合器可以应用于 min 函数,用于返回所有输入值中的最小值。它返回的结果类型为 SimpleAggregateFunction

示例用法

来看一个使用表来跟踪每日温度读数的实际示例。对于每个地点,我们希望维护记录到的最低温度。使用带有 minSimpleAggregateFunction 类型,在遇到更低的温度时会自动更新存储的值。

创建用于原始温度读数的源表:

CREATE TABLE raw_temperature_readings
(
    location_id UInt32,
    location_name String,
    temperature Int32,
    recorded_at DateTime DEFAULT now()
)
    ENGINE = MergeTree()
ORDER BY (location_id, recorded_at);

创建用于存储最小温度的聚合表:

CREATE TABLE temperature_extremes
(
    location_id UInt32,
    location_name String,
    min_temp SimpleAggregateFunction(min, Int32),  -- 存储最低温度
    max_temp SimpleAggregateFunction(max, Int32)   -- 存储最高温度
)
ENGINE = AggregatingMergeTree()
ORDER BY location_id;

创建一个增量物化视图,作为插入数据的触发器, 为每个位置维护最低和最高温度。

CREATE MATERIALIZED VIEW temperature_extremes_mv
TO temperature_extremes
AS SELECT
    location_id,
    location_name,
    minSimpleState(temperature) AS min_temp,     -- 使用 SimpleState 组合器
    maxSimpleState(temperature) AS max_temp      -- 使用 SimpleState 组合器
FROM raw_temperature_readings
GROUP BY location_id, location_name;

插入一些初始温度数据:

INSERT INTO raw_temperature_readings (location_id, location_name, temperature) VALUES
(1, '北', 5),
(2, '南', 15),
(3, '西', 10),
(4, '东', 8);

这些读数会由物化视图自动处理。我们来检查一下 当前状态:

SELECT
    location_id,
    location_name,
    min_temp,     -- 直接访问 SimpleAggregateFunction 的值
    max_temp      -- 使用 SimpleAggregateFunction 无需终结函数
FROM temperature_extremes
ORDER BY location_id;
┌─location_id─┬─location_name─┬─min_temp─┬─max_temp─┐
│           1 │ 北部          │        5 │        5 │
│           2 │ 南部          │       15 │       15 │
│           3 │ 西部          │       10 │       10 │
│           4 │ 东部          │        8 │        8 │
└─────────────┴───────────────┴──────────┴──────────┘

继续写入一些数据:

INSERT INTO raw_temperature_readings (location_id, location_name, temperature) VALUES
    (1, '北', 3),
    (2, '南', 18),
    (3, '西', 10),
    (1, '北', 8),
    (4, '东', 2);

在写入新数据后查看更新的极值:

SELECT
    location_id,
    location_name,
    min_temp,  
    max_temp
FROM temperature_extremes
ORDER BY location_id;
┌─location_id─┬─location_name─┬─min_temp─┬─max_temp─┐
│           1 │ 北部         │        3 │        8 │
│           1 │ 北部         │        5 │        5 │
│           2 │ 南部         │       18 │       18 │
│           2 │ 南部         │       15 │       15 │
│           3 │ 西部          │       10 │       10 │
│           3 │ 西部          │       10 │       10 │
│           4 │ 东部          │        2 │        2 │
│           4 │ 东部          │        8 │        8 │
└─────────────┴───────────────┴──────────┴──────────┘

请注意上面我们为每个 location 插入了两个值。这是因为 parts 还没有被合并(并且尚未被 AggregatingMergeTree 聚合)。要从这些部分状态中得到最终结果,我们需要添加一个 GROUP BY

SELECT
    location_id,
    location_name,
    min(min_temp) AS min_temp,  -- 聚合所有数据分区
    max(max_temp) AS max_temp   -- 聚合所有数据分区
FROM temperature_extremes
GROUP BY location_id, location_name
ORDER BY location_id;

现在可以看到预期的结果:

┌─location_id─┬─location_name─┬─min_temp─┬─max_temp─┐
│           1 │ 北部          │        3 │        8 │
│           2 │ 南部          │       15 │       18 │
│           3 │ 西部          │       10 │       10 │
│           4 │ 东部          │        2 │        8 │
└─────────────┴───────────────┴──────────┴──────────┘
注意

使用 SimpleState 时,就不需要再使用 Merge 组合器来合并部分聚合状态。

另请参阅