【问题标题】:How to fill missing values in aggregate-by-time function如何在按时间聚合的函数中填充缺失值
【发布时间】:2021-10-08 12:39:33
【问题描述】:

我有函数(来自this 问题),它每 5 分钟对值进行分组并计算 min/avg/max:

SELECT (FLOOR(clock / 300) * 300) as period_start,
       MIN(value), AVG(value), MAX(value)
FROM data 
WHERE clock BETWEEN 1622667600 AND 1625259600
GROUP BY FLOOR(clock / 300);

但是,由于缺少值,一些五分钟的时间段被跳过,导致时间线不一致。怎样才能让在一段时间内没有数据的情况下,max/avg/min的值变成0,而不是被跳过?

例如:

如果我有时间戳 - 值

  • 1200000001 - 100
  • 1200000002 - 300
  • 1200000301 - 100
  • 1200000601 - 300
我想得到这个:(选择 min/avg/max,时间在 1200000000 和 1200001200 之间)
  • 1200000000 - 100/200/300
  • 1200000300 - 100/100/100
  • 1200000600 - 300/300/300
  • 1200000900 - 0/0/0
而不是这个:(1200000000 和 1200001200 之间的时间)
  • 1200000000 - 100/200/300
  • 1200000300 - 100/100/100
  • 1200000600 - 300/300/300
  • 1200000900 - 这条线不会,我只会得到上面的 3 行。 1200000900 到 1200001200 之间没有数据可供计算。

【问题讨论】:

  • 以 CREATE TABLE + INSERT INTO 脚本的形式提供示例数据,并为该数据提供所需的输出并附上说明。还提供精确的 MySQL 版本。

标签: mysql sql group-by window-functions


【解决方案1】:

你可以试试这个;

with seq as (
select
    (step-1)* 300 + (select (FLOOR(min(clock) / 300) * 300) from data) as step
    from
        (select row_number() over() as step from data) tmp
    where
        tmp.step-1 < (select(max(clock)-min(clock))/ 300 from data))
SELECT seq.step as period_start, MIN(value), AVG(value), MAX(value)
FROM seq left join data on (seq.step=(FLOOR(clock / 300) * 300))
WHERE clock BETWEEN 1622667600 AND 1625259600
GROUP BY period_start

【讨论】:

    【解决方案2】:

    使用递归 CTE(从 10.2.2 开始在 MariaDB 中可用)并生成基准日历表:

    WITH RECURSIVE
    cte AS ( SELECT @timestart timestart, @timestart + 300 timeend
             UNION ALL
             SELECT timestart + 300, timeend + 300 FROM cte WHERE timeend < @timeend)
    SELECT cte.timestart, 
           COALESCE(MIN(value), 0) min_value, 
           COALESCE(AVG(value), 0) avg_value, 
           COALESCE(MAX(value), 0) max_value
    FROM cte
    LEFT JOIN example ON example.clock >= cte.timestart
                     AND example.clock < cte.timeend
    GROUP BY cte.timestart;
    

    https://dbfiddle.uk/?rdbms=mariadb_10.3&fiddle=f5c41b7596d56f1d7babe075f19302ec

    【讨论】:

      【解决方案3】:

      我不太确定,但这里有一个链接可以解决您的问题 https://www.sqlservercurry.com/2009/06/find-missing-identity-numbers-in-sql.html

      【讨论】:

        猜你喜欢
        • 2022-10-31
        • 1970-01-01
        • 1970-01-01
        • 2014-12-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-12-03
        • 2022-10-23
        相关资源
        最近更新 更多