总结来自不同流的图,但时间戳略有不同

Posted

技术标签:

【中文标题】总结来自不同流的图,但时间戳略有不同【英文标题】:sum up graphs from different streams but slightly different timestamps 【发布时间】:2015-06-03 13:27:02 【问题描述】:

现在我尝试解决一个问题,我的理解似乎与Finding gaps in huge event streams? 有某种关系

我的表中有多个数据流。我想按时间总结它们,但它们并不总是相同的时间戳。该表如下所示:

架构:

CREATE TABLE Table1
    ("id" int, "stream_id" int, "timestamp" timestamp, "value" real)
;

INSERT INTO Table1
    ("id", "stream_id", "timestamp", "value")
VALUES
    (1, 7, '2015-06-01 15:20:30', 0.1),
    (2, 7, '2015-06-01 15:20:31', 0.2),
    (3, 7, '2015-06-01 15:20:32', 0.3),
    (4, 7, '2015-06-01 15:25:30', 0.5),
    (5, 7, '2015-06-01 15:25:31', 1.0),

    (6, 6, '2015-06-01 15:20:31', 1.1),
    (7, 6, '2015-06-01 15:20:32', 1.2),
    (8, 6, '2015-06-01 15:20:33', 1.3),
    (9, 6, '2015-06-01 15:25:31', 1.5),
    (10, 6, '2015-06-01 15:25:32', 2.0)    
;

我尝试解决它:

with ts as (select "timestamp"       
           from Table1
           order by "timestamp"
          ),
data as (select "timestamp","value"
         from Table1
         order by "timestamp"
         ),
streams as (select "stream_id"        
           from Table1
           group by "stream_id"
           order by "stream_id"
          )          
select * .... (question)

我希望得到所有汇总数据的图表线。当一次,其他流中没有数据时,总和应该采用timestamp < current_timestamp 但在当前时间戳最近的行。如果没有值,则假设为 0。

我想过递归查询,但不知何故我没有看到解决方案......

编辑:这里我试图用图形解释它:

编辑 2:

我想过这样的事情,但我没有得到最后一个“东西”来完成它。

with RECURSIVE data as (
    select * from rawdata 
    where date(date_time)='2014-05-01'
),
streams as (
    select stream_id from data 
    group by stream_id
),
t(n) AS (
    VALUES (1)
  UNION ALL
    SELECT n+1 FROM t WHERE n < (select count(*) from streams)
)
SELECT n FROM t;

【问题讨论】:

我对你的要求有点困惑。您只需要每个流的总和还是按时间分桶的每个流的总和。如果您需要分桶,您的时间桶的分辨率是多少? IE。你想按分钟计算一个流的值总和吗?5 分钟?等等…… 我更新了我的问题以更好地解释它。我不想用桶或时间片来总结它们。我不知道怎么用英文解释,所以我试着用图形来解释。 你想求和多少个数字? 3个或更多?该图表明每个总和正好包含 3 个项。这是否意味着您要对最后 3 个数字求和,并且每个数字都必须来自不同的流? 我有 n 个流,每个总和由 n 个加法组成。在示例中:n = 3。和的每个元素都来自另一个流,或 0。 【参考方案1】:

抱歉,之前的查询有误 这是一个新的、更正后的查询:

WITH times AS(
  SELECT DISTINCT "timestamp" As tm
  FROM table1
)
SELECT tm, SUM( val ) as s_u_m
FROM (
    SELECT tm, "stream_id",
           (  SELECT "value" FROM Table1 t2
              WHERE t2."timestamp" = max( t1."timestamp" )
                AND t2."stream_id" = t1."stream_id"
              ORDER BY "id" DESC LIMIT 1
            ) As val
    FROM times t
    JOIN table1 t1
    ON t.tm >= t1."timestamp"
    GROUP BY tm, "stream_id"
    order by tm
  ) you_must_have_an_alias_here_in_order_to_avoid_the_syntax_error
GROUP BY tm
ORDER BY tm;
;

以及源数据中包含 3 个流的演示:http://sqlfiddle.com/#!15/30eb8/5


这是一个具有模仿图表布局的布局的源表:

|  x | id |              timestamp | stream6 | stream7 | stream8 |
|----|----|------------------------|---------|---------|---------|
|  1 |  1 | June, 01 2015 15:20:30 |  (null) |     0.1 |  (null) |
|  2 |  2 | June, 01 2015 15:20:31 |  (null) |     0.2 |  (null) |
|  3 |  3 | June, 01 2015 15:20:31 |     1.1 |  (null) |  (null) |
|  4 |  4 | June, 01 2015 15:20:32 |  (null) |     0.3 |  (null) |
|  5 |  5 | June, 01 2015 15:20:32 |     1.2 |  (null) |  (null) |
|  6 | 11 | June, 01 2015 15:20:32 |  (null) |  (null) |     2.3 |
|  7 | 12 | June, 01 2015 15:20:32 |  (null) |  (null) |     1.1 |
|  8 | 10 | June, 01 2015 15:20:33 |     1.3 |  (null) |  (null) |
|  9 | 13 | June, 01 2015 15:20:33 |  (null) |  (null) |     1.7 |
| 10 |  6 | June, 01 2015 15:25:30 |  (null) |     0.5 |  (null) |
| 11 |  7 | June, 01 2015 15:25:31 |     1.5 |  (null) |  (null) |
| 12 |  8 | June, 01 2015 15:25:31 |  (null) |       1 |  (null) |
| 13 |  9 | June, 01 2015 15:25:32 |       2 |  (null) |  (null) |

结果是:(v(3) 表示:来自 x=3 的记录的值)

|                     tm |     s_u_m |
|------------------------|-----------|
| June, 01 2015 15:20:30 |       0.1 |  0    + v(1) + 0
| June, 01 2015 15:20:31 | 1.3000001 |  v(3) + v(2)  + 0
| June, 01 2015 15:20:32 |       2.6 |  v(5) + v(4) + v(7) => see note below !!!
| June, 01 2015 15:20:33 |       3.3 |  v(8) + v(4) + v(9)
| June, 01 2015 15:25:30 |       3.5 |  v(8) + v(10)+ v(9)
| June, 01 2015 15:25:31 |       4.2 |  v(11)+ v(12)+ v(9)
| June, 01 2015 15:25:32 |       4.7 |  v(13)+ v(12)+ v(9)

注意事项 | June, 01 2015 15:20:32 | 2.6 | 演示中的源表包含两条日期相同且source_id相同的记录:

|  6 | 11 | June, 01 2015 15:20:32 |  (null) |  (null) |     2.3 |
|  7 | 12 | June, 01 2015 15:20:32 |  (null) |  (null) |     1.1 |

由于此代码片段中的ORDER BY "id" DESC,查询仅获取最新记录 x=7:

(  SELECT "value" FROM Table1 t2
      WHERE t2."timestamp" = max( t1."timestamp" )
        AND t2."stream_id" = t1."stream_id"
      ORDER BY "id" DESC LIMIT 1
    ) As val

如果您想获取第一条记录 x=6 而不是最新记录,请从 order by 子句中删除 DESC。 如果您想对所有具有相同日期和 stream_id 的记录求和(在上面的示例中 - 记录 6 + 7),则将上述查询更改为:

(  SELECT SUM("value") FROM Table1 t2
      WHERE t2."timestamp" = max( t1."timestamp" )
        AND t2."stream_id" = t1."stream_id"
    ) As val

如果你想获取随机记录,那么使用ORDER BY random()

【讨论】:

由于我提供的示例数据,并没有满足“ids和timestamp”按时间排序的要求,所以fiddle中的结果是不正确的。 这里我将输入数据更改为要求,但似乎不正确。 sqlfiddle.com/#!15/00ae2/1/0 我已经更正了查询,请看一下。 哇!我只是坐在那里并没有得到它......我印象深刻!谢谢!

以上是关于总结来自不同流的图,但时间戳略有不同的主要内容,如果未能解决你的问题,请参考以下文章

对时间戳略有差异的时间序列求和

在时间戳略有不同的2个不同数据库中的表之间连接(MySQL)

具有相同时间戳但测量值不同的 InfluxDB 写入点

MySQL 按时间戳分组/排序不能按预期工作

Firebase 服务器时间戳与正确时间不同

PHP时间戳函数总结