将时间序列数据映射到另一个时间序列db2

时间:2017-12-21 12:35:21

标签: sql join db2 time-series ibm-cloud

我正在尝试将两个SQL(IBM on bluemix上的DB2)查询的结果组合在一起:

第一个查询创建一个从startdate到enddate的时间序列:

with dummy(minute) as (
      select TIMESTAMP('2017-01-01')
      from SYSIBM.SYSDUMMY1 union all
      select minute + 1 MINUTES
      from dummy
      where minute <= TIMESTAMP('2018-01-01')
     )
select to_char(minute, 'DD.MM.YYYY HH24:MI') AS minute
from dummy;

The result is looking like this

第二个查询从具有时间戳的表中选择数据。此数据应与上面生成的时间序列连接。独立查询如下:

SELECT DISTINCT
  to_char(date_trunc('minute', TIMESTAMP), 'DD.MM.YYYY HH24:MI') AS minute,
  VALUE AS running_ct
FROM TEST
WHERE ID = 'abc'
AND NAME = 'sensor'
ORDER BY minute ASC;

The result is looking like this

我想要得到的是一个包含两列的结果的查询:

  • 第一列,时间戳从startdate到enddate和
  • 第二个值,按照自己的时间戳排序到
  • 第一列(空时间戳= null)。

我怎么能这样做?

2 个答案:

答案 0 :(得分:0)

找到了一个有效的解决方案:

    with dummy(temporaer) as (
     select TIMESTAMP('2017-12-01') from SYSIBM.SYSDUMMY1
     union all
     select temporaer + 1 MINUTES from dummy where temporaer <= TIMESTAMP('2018-01-31'))
    select temporaer, avg(VALUE) as text from dummy
    LEFT OUTER JOIN TEST ON temporaer=date_trunc('minute', TIMESTAMP) and ID='abc' and NAME='text'
    group by temporaer
    ORDER BY temporaer ASC;

欢呼声

答案 1 :(得分:0)

更好的解决方案,特别是如果您的详细信息表很大,就是生成范围。这允许优化器使用索引来完成bucketing,而不是在每一行上调用一个函数(这很昂贵)。

这样的事情:

WITH dummy(temporaer, rangeEnd) AS (SELECT a, a + 1 MINUTE 
                                    FROM (VALUES(TIMESTAMP('2017-12-01'))) D(a)
                                    UNION ALL
                                    SELECT rangeEnd, rangeEnd + 1 MINUTE
                                    FROM dummy
                                    WHERE rangeEnd < TIMESTAMP('2018-01-31'))
SELECT Dummy.temporaer, AVG(Test.value) AS TEXT
FROM Dummy
LEFT OUTER JOIN Test
             ON Test.timestamp >= Dummy.temporaer
                AND Test.timestamp < Dummy.rangeEnd
                AND Test.id = 'abc'
                AND Test.name = 'text'
GROUP BY Dummy.temporaer
ORDER BY Dummy.temporaer ASC;

请注意,范围的结尾现在是独占,不像以前那样具有包容性:你包括'2018-01-31'的第一分钟,这可能不是你想要的。当然,除了一个月的最后一天也让我觉得有点奇怪 - 你很可能真的想要< TIMESTAMP('2018-02-01')