Clickhouse SQL 查询:区间平均值

Clickhouse SQL Query: Average in intervals

我有一个table: deviceId, valueDateTime, value, valueType

其中 valueType - 温度、压力等

我有几个查询参数:begin、end(period)、time interval(比如20分钟) 我想获取每个 deviceId 和 valueType 的周期图表,以及该周期中每个间隔的一系列平均值。

编辑: 以上是最后的任务,目前我只是在试验这个任务,我使用 https://play.clickhouse.tech/?file=playground 来尝试解决类似的任务。我想计算按标题字段分组的时间间隔内的平均年龄。我有一个问题,如何按标题添加分组?

-- 2013-07-15 00:00:00 - begin
-- 2013-07-16 00:00:00 - end
-- 1200 - average in interval 20m

SELECT t, avg(Age) as Age FROM (
    SELECT 
        arrayJoin(
          arrayMap(x -> addSeconds(toDateTime('2013-07-15 00:00:00'), x * 1200),
              range(toUInt64(dateDiff('second', toDateTime('2013-07-15 00:00:00'), toDateTime('2013-07-16 00:00:00'))/1200)))
        ) as t,
        null as Age

    UNION ALL

    SELECT
        (addSeconds(
          toDateTime('2013-07-15 00:00:00'), 
          1200 * intDivOrZero(dateDiff('second', toDateTime('2013-07-15 00:00:00'), EventTime), 1200))
        ) as t,
        avg(Age) as Age
        FROM `hits_100m_obfuscated`
        WHERE EventTime BETWEEN toDateTime('2013-07-15 00:00:00') AND toDateTime('2013-07-16 00:00:00')
        GROUP BY t
)
GROUP BY t ORDER BY t;

已编辑 2 vladimir 的正确答案适合在 https://play.clickhouse.tech/?file=playground

上使用和测试
SELECT
    Title,                                        -- as deviceId
    JavaEnable,                                   -- as valueType
    groupArray((rounded_time, avg_value)) values
FROM (
  WITH 60 * 20 AS interval
  SELECT 
    Title, 
    JavaEnable,
    toDateTime(intDiv(toUInt32(EventTime), interval) * interval) 
      AS rounded_time,                            -- EventTime as valueDateTime
    avg(Age) avg_value                            -- Age as value
  FROM `hits_100m_obfuscated`
  WHERE 
    EventTime BETWEEN toDateTime('2013-07-15 00:00:00') 
                  AND toDateTime('2013-07-16 00:00:00')
  GROUP BY 
    Title, 
    JavaEnable, 
    rounded_time
  ORDER BY rounded_time
)
GROUP BY 
    Title,
    JavaEnable
ORDER BY
    Title,
    JavaEnable

试试这个查询:

SELECT
    deviceId,
    valueType,
    groupArray((rounded_time, avg_value)) values
FROM (
  WITH 60 * 20 AS interval
  SELECT 
    deviceId, 
    valueType,
    toDateTime(intDiv(toUInt32(valueDateTime), interval) * interval) AS rounded_time,
    avg(value) avg_value
  FROM 
  (
      /* emulate the test dataset */
      SELECT
          number % 4 AS deviceId,
          now() - (number * 60) AS valueDateTime,
          number % 10 AS value,
          if((number % 2) = 1, 'temp', 'pres') AS valueType
      FROM numbers(48)
  ) 
  /*WHERE valueDateTime >= begin AND valueDateTime < end */
  GROUP BY 
    deviceId, 
    valueType, 
    rounded_time
  ORDER BY rounded_time
)
GROUP BY 
    deviceId,
    valueType
ORDER BY
    deviceId,
    valueType

/*
┌─deviceId─┬─valueType─┬─values────────────────────────────────────────────────────────────────────────────────────────────────────┐
│        0 │ pres      │ [('2021-02-12 06:00:00',4),('2021-02-12 06:20:00',4),('2021-02-12 06:40:00',4),('2021-02-12 07:00:00',0)] │
│        1 │ temp      │ [('2021-02-12 06:00:00',5),('2021-02-12 06:20:00',5),('2021-02-12 06:40:00',5),('2021-02-12 07:00:00',1)] │
│        2 │ pres      │ [('2021-02-12 06:00:00',4),('2021-02-12 06:20:00',4),('2021-02-12 06:40:00',4)]                           │
│        3 │ temp      │ [('2021-02-12 06:00:00',5),('2021-02-12 06:20:00',5),('2021-02-12 06:40:00',5)]                           │
└──────────┴───────────┴───────────────────────────────────────────────────────────────────────────────────────────────────────────┘
*/

我建议使用 Grafana 可视化 CH 报告(参见 Grafana ClickHouse datasource)。