如何根据时间戳组合表

时间:2018-04-11 21:54:17

标签: sql vertica

想象一下,你有两个事件表。表A和表B都有一个列,称为时间戳,有多行。

现在我想将这两个表组合成一个具有以下属性的表C:

  • C在A
  • 中的每一行都有一行
  • C有一个时间戳列,完美地反映了A
  • 的内容
  • C有另一个名为near_event的列,如果在该行的时间戳的1s内有B行,则为true,否则为false

我怎样才能有效地做到这一点?

2 个答案:

答案 0 :(得分:2)

mauro向我指出了这一点,说Vertica可以做得更好 - 事实上,它可以,因为它有一个谓词,可以实现我们所谓的事件系列连接。您需要做的就是运行非内连接(左,右或全外)并智能地使用INTERPOLATE PREVIOUS VALUE作为连接谓词。

您可能想查看我的LinkedIn帖子:

https://www.linkedin.com/pulse/verticas-event-series-join-joining-two-time-tables-marco-gessner/

..这说明了一个更复杂的用例。

使用与该博客相同的表格:

CREATE LOCAL TEMPORARY TABLE oilpressure (
 op_ts,op_psi
) ON COMMIT PRESERVE ROWS AS (
          SELECT TIMESTAMP '2015-04-01 07:00:00', 25.356
UNION ALL SELECT TIMESTAMP '2015-04-01 07:00:10', 35.124
UNION ALL SELECT TIMESTAMP '2015-04-01 07:00:20', 47.056
UNION ALL SELECT TIMESTAMP '2015-04-01 07:00:30', 45.225
)
;

CREATE LOCAL TEMPORARY TABLE revspeed (
 rs_ts,rpm
) ON COMMIT PRESERVE ROWS AS (
          SELECT TIMESTAMP '2015-04-01 07:00:00', 2201
UNION ALL SELECT TIMESTAMP '2015-04-01 07:00:08', 3508
UNION ALL SELECT TIMESTAMP '2015-04-01 07:00:15', 6504
UNION ALL SELECT TIMESTAMP '2015-04-01 07:00:20', 6608
)
;

oilpressure成为您的表格A,revspeed成为您的表格B.

然后您想要的(如果您只想要时间戳)是:

SELECT
  op_ts
, rs_ts
FROM oilpressure
LEFT JOIN revspeed
ON op_ts INTERPOLATE PREVIOUS VALUE rs_ts;
op_ts              |rs_ts
2015-04-01 07:00:00|2015-04-01 07:00:00
2015-04-01 07:00:10|2015-04-01 07:00:08
2015-04-01 07:00:20|2015-04-01 07:00:20
2015-04-01 07:00:30|2015-04-01 07:00:20

答案 1 :(得分:1)

如果您没有太多重复项,您可以这样做。这是一个想法:

select timestamp,
       (case when timestamp < timestamp_add(second, 1, last_b_timestamp) or
                  timestamp > timestamp_add(second, -1, next_b_timestamp)
             then 1 else 0
        end) as flag
from (select timestamp, which,
             last_value(case when which = 'b' then timestamp) over (order by timestamp) as last_b_timestamp,
             last_value(case when which = 'b' then timestamp) over (order by timestamp desc) as next_b_timestamp,
      from ((select a.timestamp, 'a' as which from a) union all
            (select b.timestamp, 'b' as which from b)
           ) ab
     ) ab
where which = 'a';