如何根据时间戳组合表
How to combine tables based on timestamps
假设您有两个 table 事件。 tables A 和 B 都有一个列,称为时间戳,有多个行。
现在我想将这两个 table 组合成具有以下属性的 table C:
- C 对应 A 中的每一行
- C有一个时间戳列,完美反映了A的内容
- C 有另一个名为 near_event 的列,如果 B 中有一行在该行时间戳的 1 秒内,则为 true,否则为 false
我怎样才能有效地做到这一点?
如果您没有太多重复项,您也许可以这样做。思路如下:
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';
mauro 向我指出了这一点,他说 Vertica 可以做得更好 - 事实上,它可以,因为它有一个谓词可以实现我们所说的 event series join.您需要做的就是 运行 一个非内部连接(左、右或完全外部)并智能地使用 INTERPOLATE PREVIOUS VALUE
作为连接谓词。
你可能想看看我的 LinkedIn post :
https://www.linkedin.com/pulse/verticas-event-series-join-joining-two-time-tables-marco-gessner/
.. 这说明了一个更复杂的用例。
使用与该博客中相同的 table:
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
成为你的table A,让revspeed
成为你的table 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
假设您有两个 table 事件。 tables A 和 B 都有一个列,称为时间戳,有多个行。
现在我想将这两个 table 组合成具有以下属性的 table C:
- C 对应 A 中的每一行
- C有一个时间戳列,完美反映了A的内容
- C 有另一个名为 near_event 的列,如果 B 中有一行在该行时间戳的 1 秒内,则为 true,否则为 false
我怎样才能有效地做到这一点?
如果您没有太多重复项,您也许可以这样做。思路如下:
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';
mauro 向我指出了这一点,他说 Vertica 可以做得更好 - 事实上,它可以,因为它有一个谓词可以实现我们所说的 event series join.您需要做的就是 运行 一个非内部连接(左、右或完全外部)并智能地使用 INTERPOLATE PREVIOUS VALUE
作为连接谓词。
你可能想看看我的 LinkedIn post :
https://www.linkedin.com/pulse/verticas-event-series-join-joining-two-time-tables-marco-gessner/
.. 这说明了一个更复杂的用例。
使用与该博客中相同的 table:
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
成为你的table A,让revspeed
成为你的table 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