Как в ClickHouse при выравнивании показаний датчиков по меткам времени с нужным шагом вместо 0 получить предыдущее реальное показание датчика?
- В ClickHouse для хранения показаний датчиков создана таблица indications со следующей структурой:
CREATE TABLE indications (
`unit_id` UInt16 CODEC(DoubleDelta, ZSTD(1)),
`sensor_name` String CODEC(ZSTD(1)),
`date_time_utc` DateTime('UTC') CODEC(Delta(4), ZSTD(1)),
`period_sec` UInt32 CODEC(DoubleDelta, ZSTD(1)),
`indication` Decimal(18, 7) CODEC(Delta(8), ZSTD(1))
) ENGINE = ReplacingMergeTree() PARTITION BY (unit_id, toYYYYMM(date_time_utc), period_sec)
ORDER BY
(unit_id, sensor_name, date_time_utc, period_sec) SETTINGS index_granularity = 8192
- Строки в таблицу добавляются только при изменении показания датчика.
- Для отладки запросов добавим в таблицу indications следующие тестовые показания датчика:
insert into indications values
(8, 'First', '2021-04-01 00:00:00', 1, 0),
(8, 'First', '2021-04-01 05:00:00', 1, 5),
(8, 'First', '2021-04-01 08:00:00', 1, 8),
(8, 'First', '2021-04-01 08:20:00', 1, 6),
(8, 'First', '2021-04-01 08:40:00', 1, 7),
(8, 'First', '2021-04-01 09:00:00', 1, 0),
(8, 'First', '2021-04-01 11:00:00', 1, 11),
(8, 'First', '2021-04-01 13:00:00', 1, 0)
- Для выравнивания показаний датчиков по меткам времени с нужным шагом (например в 1 час) использую конструкцию ORDER BY ... WITH FILL
select
i.date_time_utc,
i.indication,
neighbor(i.indication, -1) as prev_ind,
neighbor(i.date_time_utc, -1) as prev_date
from
indications as i
where
i.unit_id = 8
and i.sensor_name = 'First'
and i.date_time_utc >= '2021-04-01 00:00:00'
order by i.date_time_utc with fill step 60*60
в результат добавятся строки с метками времени с нужным шагом но с нулевыми значениями, а мне вместо нулей нужно предыдущее сохраненное реальное показание датчика.
| date_time_utc | indication | prev_ind | prev_date |
|---|---|---|---|
| 2021-04-01 00:00:00 | 0 | 0 | 0000-00-00 00:00:00 |
| 2021-04-01 01:00:00 | 0 | 0 | 0000-00-00 00:00:00 |
| 2021-04-01 02:00:00 | 0 | 0 | 0000-00-00 00:00:00 |
| 2021-04-01 03:00:00 | 0 | 0 | 0000-00-00 00:00:00 |
| 2021-04-01 04:00:00 | 0 | 0 | 0000-00-00 00:00:00 |
| 2021-04-01 05:00:00 | 5 | 0 | 2021-04-01 00:00:00 |
| 2021-04-01 06:00:00 | 0 | 0 | 0000-00-00 00:00:00 |
| 2021-04-01 07:00:00 | 0 | 0 | 0000-00-00 00:00:00 |
| 2021-04-01 08:00:00 | 8 | 5 | 2021-04-01 05:00:00 |
| 2021-04-01 08:20:00 | 6 | 8 | 2021-04-01 08:00:00 |
| 2021-04-01 08:40:00 | 7 | 6 | 2021-04-01 08:20:00 |
| 2021-04-01 09:00:00 | 0 | 7 | 2021-04-01 08:40:00 |
| 2021-04-01 10:00:00 | 0 | 0 | 0000-00-00 00:00:00 |
| 2021-04-01 11:00:00 | 11 | 0 | 2021-04-01 09:00:00 |
| 2021-04-01 12:00:00 | 0 | 0 | 0000-00-00 00:00:00 |
| 2021-04-01 13:00:00 | 0 | 11 | 2021-04-01 11:00:00 |
- Чтобы отличить реальные нулевые показания датчиков от строк пустышек добавил колонку ind в которой нулевые значения, требующие замены на предыдущие показания, заменены на -1
select
aligned.*,
if(aligned.indication=0 and aligned.prev_ind=0, toDecimal64(-1,7), aligned.indication) as ind
from
(
select
i.date_time_utc,
i.indication,
neighbor(i.indication, -1) as prev_ind,
neighbor(i.date_time_utc, -1) as prev_date
from
indications as i
where
i.unit_id = 8
and i.sensor_name = 'First'
and i.date_time_utc >= '2021-04-01 00:00:00'
order by i.date_time_utc with fill step 60*60
) as aligned
| date_time_utc | indication | prev_ind | prev_date | ind |
|---|---|---|---|---|
| 2021-04-01 00:00:00 | 0 | 0 | 0000-00-00 00:00:00 | -1 |
| 2021-04-01 01:00:00 | 0 | 0 | 0000-00-00 00:00:00 | -1 |
| 2021-04-01 02:00:00 | 0 | 0 | 0000-00-00 00:00:00 | -1 |
| 2021-04-01 03:00:00 | 0 | 0 | 0000-00-00 00:00:00 | -1 |
| 2021-04-01 04:00:00 | 0 | 0 | 0000-00-00 00:00:00 | -1 |
| 2021-04-01 05:00:00 | 5 | 0 | 2021-04-01 00:00:00 | 5 |
| 2021-04-01 06:00:00 | 0 | 0 | 0000-00-00 00:00:00 | -1 |
| 2021-04-01 07:00:00 | 0 | 0 | 0000-00-00 00:00:00 | -1 |
| 2021-04-01 08:00:00 | 8 | 5 | 2021-04-01 05:00:00 | 8 |
| 2021-04-01 08:20:00 | 6 | 8 | 2021-04-01 08:00:00 | 6 |
| 2021-04-01 08:40:00 | 7 | 6 | 2021-04-01 08:20:00 | 7 |
| 2021-04-01 09:00:00 | 0 | 7 | 2021-04-01 08:40:00 | 0 |
| 2021-04-01 10:00:00 | 0 | 0 | 0000-00-00 00:00:00 | -1 |
| 2021-04-01 11:00:00 | 11 | 0 | 2021-04-01 09:00:00 | 11 |
| 2021-04-01 12:00:00 | 0 | 0 | 0000-00-00 00:00:00 | -1 |
| 2021-04-01 13:00:00 | 0 | 11 | 2021-04-01 11:00:00 | 0 |
Подскажите пожалуйста, как в колонке ind вместо -1 получить предыдущее реальное показание датчика ?