minSimpleState — 모든 입력 값의 최솟값을 단순 상태로 구하기
minSimpleState — 모든 입력 값의 최솟값을 단순 상태로 구하기
minSimpleState는 min 함수에 SimpleState 결합자를 적용해서 모든 입력 값 중 최솟값을 SimpleAggregateFunction 타입으로 반환하는 방법을 보여드릴게요.
출처: 문서
본문
min 함수에 SimpleState 결합자를 적용하면 모든 입력 값 중 최솟값을 반환해요. 결과는 SimpleAggregateFunction 타입으로 반환해요.
일일 온도 측정값을 추적하는 테이블을 사용하는 실용적인 예제를 살펴볼게요. 각 위치에 대해 기록된 최저 온도를 유지하고 싶다고 해요. min과 함께 SimpleAggregateFunction 타입을 사용하면 더 낮은 온도가 들어올 때 저장된 값을 자동으로 갱신해요. 원시 온도 측정값을 위한 원본 테이블을 만들어요:
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), -- Stores minimum temperature
max_temp SimpleAggregateFunction(max, Int32) -- Stores maximum temperature
)
ENGINE = AggregatingMergeTree()
ORDER BY location_id;
삽입된 데이터에 대한 삽입 트리거 역할을 하면서 위치별 최저·최고 온도를 유지하는 Incremental materialized view를 만들어요:
CREATE MATERIALIZED VIEW temperature_extremes_mv
TO temperature_extremes
AS SELECT
location_id,
location_name,
minSimpleState(temperature) AS min_temp, -- Using SimpleState combinator
maxSimpleState(temperature) AS max_temp -- Using SimpleState combinator
FROM raw_temperature_readings
GROUP BY location_id, location_name;
초기 온도 측정값을 삽입해요:
INSERT INTO raw_temperature_readings (location_id, location_name, temperature) VALUES
(1, 'North', 5),
(2, 'South', 15),
(3, 'West', 10),
(4, 'East', 8);
이 측정값들은 materialized view가 자동으로 처리해요. 현재 상태를 확인해볼게요:
SELECT
location_id,
location_name,
min_temp, -- Directly accessing the SimpleAggregateFunction values
max_temp -- No need for finalization function with SimpleAggregateFunction
FROM temperature_extremes
ORDER BY location_id;
┌─location_id─┬─location_name─┬─min_temp─┬─max_temp─┐
│ 1 │ North │ 5 │ 5 │
│ 2 │ South │ 15 │ 15 │
│ 3 │ West │ 10 │ 10 │
│ 4 │ East │ 8 │ 8 │
└─────────────┴───────────────┴──────────┴──────────┘
데이터를 더 삽입해요:
INSERT INTO raw_temperature_readings (location_id, location_name, temperature) VALUES
(1, 'North', 3),
(2, 'South', 18),
(3, 'West', 10),
(1, 'North', 8),
(4, 'East', 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 │ North │ 3 │ 8 │
│ 1 │ North │ 5 │ 5 │
│ 2 │ South │ 18 │ 18 │
│ 2 │ South │ 15 │ 15 │
│ 3 │ West │ 10 │ 10 │
│ 3 │ West │ 10 │ 10 │
│ 4 │ East │ 2 │ 2 │
│ 4 │ East │ 8 │ 8 │
└─────────────┴───────────────┴──────────┴──────────┘
위에서 각 위치마다 두 개의 삽입된 값이 보이는데요, 아직 part들이 병합(그리고 AggregatingMergeTree에 의한 집계)되지 않았기 때문이에요. 부분 상태에서 최종 결과를 얻으려면 GROUP BY를 추가해야 해요:
SELECT
location_id,
location_name,
min(min_temp) AS min_temp, -- Aggregate across all parts
max(max_temp) AS max_temp -- Aggregate across all parts
FROM temperature_extremes
GROUP BY location_id, location_name
ORDER BY location_id;
이제 기대한 결과를 얻을 수 있어요:
┌─location_id─┬─location_name─┬─min_temp─┬─max_temp─┐
│ 1 │ North │ 3 │ 8 │
│ 2 │ South │ 15 │ 18 │
│ 3 │ West │ 10 │ 10 │
│ 4 │ East │ 2 │ 8 │
└─────────────┴───────────────┴──────────┴──────────┘
SimpleState를 사용하면 부분 집계 상태를 합치기 위해 Merge 결합자를 쓸 필요가 없어요.