Материализованное представление с механизмом AggregatingMergeTree удаляет записи вместо агрегации

#clickhouse

Вопрос:

Допустим, у меня есть следующая таблица

 CREATE TABLE trades (
  `ts` DateTime64(9, 'UTC'), 
  `volume` Decimal(40, 20),
  `market` String
) ENGINE = MergeTree ORDER BY (market, ts)
 

и материализованный вид поверх него

 CREATE MATERIALIZED VIEW trades_per_hour 
ENGINE = AggregatingMergeTree()
ORDER BY (market, ts_1h)
AS (
    SELECT sum(volume) as volume, ts_1h, market
    FROM trades 
    GROUP BY market, toStartOfHour(ts) as ts_1h
)
 

Я вставляю туда пару записей:

 INSERT INTO trades (*) VALUES ('2021-01-01 01:08:00', '1.5', 'EUR')
INSERT INTO trades (*) VALUES ('2021-01-01 01:09:00', '3.7', 'EUR')
 

таким образом, таблица выглядит следующим образом

 ┌────────────────────────────ts─┬─────────────────volume─┬─market─┐
│ 2021-01-01 01:08:00.000000000 │ 1.50000000000000000000 │ EUR    │
└───────────────────────────────┴────────────────────────┴────────┘
┌────────────────────────────ts─┬─────────────────volume─┬─market─┐
│ 2021-01-01 01:09:00.000000000 │ 3.70000000000000000000 │ EUR    │
└───────────────────────────────┴────────────────────────┴────────┘
 

Теперь материализованный вид без группировки по отображает две строки (я предполагаю, что это ожидаемо).:

 SELECT * FROM trades_per_hour;

┌─────────────────volume─┬───────────────ts_1h─┬─market─┐
│ 3.70000000000000000000 │ 2021-01-01 01:00:00 │ EUR    │
└────────────────────────┴─────────────────────┴────────┘
┌─────────────────volume─┬───────────────ts_1h─┬─market─┐
│ 1.50000000000000000000 │ 2021-01-01 01:00:00 │ EUR    │
└────────────────────────┴─────────────────────┴────────┘
 

если запрос выполняется с помощью предложения group, он показывает:

 SELECT sum(volume), ts_1h FROM trades_per_hour GROUP BY ts_1h;

┌────────────sum(volume)─┬───────────────ts_1h─┐
│ 5.20000000000000000000 │ 2021-01-01 01:00:00 │
└────────────────────────┴─────────────────────┘
 

тогда, если я это сделаю

 OPTIMIZE TABLE trades_per_hour;
 

У меня осталась только одна строка (наверное, из-за дедупликации?):

 ┌─────────────────volume─┬───────────────ts_1h─┬─market─┐
│ 1.50000000000000000000 │ 2021-01-01 01:00:00 │ EUR    │
└────────────────────────┴─────────────────────┴────────┘
 

таким образом, строка с томом 3.7 была просто удалена.

Чего я на самом деле ожидаю, так это

 ┌─────────────────volume─┬───────────────ts_1h─┬─market─┐
│ 5.20000000000000000000 │ 2021-01-01 01:00:00 │ EUR    │
└────────────────────────┴─────────────────────┴────────┘
 

таким образом, «дубликаты» для каждого ts_1h market фактически объединяются вместе.

Я хотел бы спросить, что я делаю не так в моей таблице и / или определении материализованного представления.

Любая помощь приветствуется. Приветствия.

Ответ №1:

Он должен использовать AggregateFunction / SimpleAggregateFunction:

 CREATE MATERIALIZED VIEW trades_per_hour 
(
  ts_1h DateTime64(9, 'UTC'),
  volume SimpleAggregateFunction(sum, Decimal(40, 20)),
  market String
)
ENGINE = AggregatingMergeTree()
PARTITION BY toYYYYMM(ts_1h)
ORDER BY (market, ts_1h)
AS 
SELECT toStartOfHour(ts) as ts_1h, sum(volume) as volume, market
FROM trades 
GROUP BY market, ts_1h
 

Комментарии:

1. Большое спасибо, Владимир. Не знал, что я мог бы заранее определить схему MV и дать ей подсказку о функции агрегирования. Это прекрасно работает!