【问题标题】:SQL Time Series Group with max amount of results具有最大结果量的 SQL 时间序列组
【发布时间】:2022-11-07 16:51:25
【问题描述】:

我在使用 Timescaledb 的表中有时间序列数据。

数据如下:

    time                    locationid parameterid unitid value
2022-04-18T10:00:00.000Z      "1"        "1"        "2"    2.2
2022-04-18T10:00:00.000Z      "2"        "1"        "2"    3.0
2022-04-18T09:00:00.000Z      "1"        "1"        "2"    1.2
2022-04-18T09:00:00.000Z      "2"        "1"        "2"    4.0
2022-04-18T08:00:00.000Z      "1"        "1"        "2"    2.6
2022-04-18T08:00:00.000Z      "2"        "1"        "2"    3.1
2022-04-18T07:00:00.000Z      "1"        "1"        "2"    2.1
2022-04-18T07:00:00.000Z      "2"        "1"        "2"    2.7

我有 1000 行包含时间序列 IOT 数据的行,我正在使用 HighCharts 将这些数据放入图表中。

我的问题是,有没有办法限制我的结果中返回的项目数量,但不是经典限制。我想始终返回 256 个数据组。因此,如果我有 2,560 行,我的查询将按/日期 trunc / time_bucket 每 100 行分组,但如果我有 512 行,我的查询只会每 2 行分组一次,因此无论如何我总是返回 256。

我目前的查询:

SELECT time_bucket('4 hours', time) as "t"
,locationid, avg(timestamp) as "x", avg(value) as "y"
FROM probe_data
WHERE locationid = '${q.locationid}'and parameterid = '${q.parameterid}' 
and time > '${q.startDate}' and time < `${q.endDate}`
GROUP BY "t", locationid
ORDER BY "t" DESC;

似乎我应该能够使用我的最小日期和最大日期来计算可能返回的数量,然后除以 256?这是最好的方法吗?

【问题讨论】:

  • 时间都已经等距了吗?
  • 是的,每个 locationid 的每次读数相隔 1 小时。
  • @gsmith1515 这是一个很好的问题(我来自 TimescaleDB)。如果我将它添加到我们的论坛以便其他用户可以找到它,我希望你没问题......如果你想要信用并且更喜欢自己写它,尽管让我知道!
  • @greenweeds 加油!
  • 花了我一段时间,但我现在做到了,谢谢!

标签: sql group-by timescaledb


【解决方案1】:

有几种不同的方法可以做这样的事情:

  1. 您可以使用time_bucket 更改您在查询中动态使用的时间段。您可以对区间进行算术运算并返回另一个区间,即SELECT (now()- '2022-04-21')/256; 将返回一个区间,这可以是time_bucket 的第一个输入。所以像
    SELECT time_bucket((enddate - startdate) / 256, time) as "t" 
    ...
    GROUP BY time_bucket((enddate - startdate) / 256, time)
    

    应该在很大程度上做你正在寻找的东西......

    但是,这确实意味着当您缩小时您将获得任意更大的数据组的平均值,并且不允许您缓存东西或类似的东西,并且可能实际上并不是底层过程的一个很好的表示.

    另一种选择是:

    1. 您可以在与您的数据分析相关的设定 time_bucket 处进行平均,然后使用诸如最大三角形三桶之类的算法进行下采样,该算法在对数据进行下采样的同时以一种有用的方式保持图形的视觉准确性。 It's one of the experimental hyperfunctions that we have in TimescaleDB。

    这将允许您还可以使用 continuous aggregates 之类的东西使用一组 time_bucket 对数据进行下采样,然后使用 LTTB 算法更快地获得图形所需的点数。

    所以它有点取决于你在寻找什么......在某些情况下,在不做平均的情况下单独使用 LTTB,甚至使用像 ASAP smoothing (another experimental hyperfunction) 这样的东西可能是一种更好的方式来做你正在寻找和建造的东西-从事这类工作!我认为文档页面有更多关于算法的信息以及它们的用途,但是 LTTB 和 ASAP 都是专门为图形应用程序设计的,所以我想我会指出它们!

【讨论】:

    【解决方案2】:

    否 - SQL 不支持动态分组。要按照您的要求进行操作,您必须获取结果集并检查返回的记录数,然后使用您的逻辑再次运行。

    实际上,您遇到了表示级别的问题 - 而不是 SQL 问题。

    【讨论】:

    • 很高兴看到你的回答!预计到 2032 年还会有一个
    • 我同意@MartinSmith。
    【解决方案3】:

    可能是NTILE,不确定这是否可行,但我想这样做:

    SELECT avg(sub.timestamp), avg(sub.value) FROM (
        SELECT 
            timestamp,
            value,
            NTILE (256) OVER (
                ORDER BY time
           ) bucket_no
        FROM 
            probe_data
    ) sub GROUP BY sub.bucket_no;
    

    内部查询将您的所有数据分成 256 个组,然后每个组将有一个列 bucket_no,而您的外部查询将按 bucket_no 分组

    编辑:刚刚意识到这个问题上的mysql 标签可能不准确,但我会留下答案,因为它可能会为您指明 timescaledb 的正确方向。

    【讨论】:

    • 好电话,我刚刚删除了 mysql 标签。感谢您的帮助,我会看看这个,看看我能想出什么。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-12
    • 2020-05-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多