SQL: vertica 中的高级时间片
SQL: Advanced time slice in vertica
大家好:我在 vertica 数据库中有以下 table:
+-----+------+----------+
| Tid | item | time_sec |
+-----+------+----------+
| 1 | A | 1 |
| 1 | B | 2 |
| 1 | C | 4 |
| 1 | D | 5 |
| 1 | E | 6 |
| 2 | A | 5 |
| 2 | E | 5 |
+-----+------+----------+
我的目标是在时间 window deltaT 内创建新的项目组。这意味着第一个和最后一个项目的时间戳之间的差异小于或等于 deltaT。示例:如果 deltaT = 2 秒,我们将得到新的 table:
+-----+------+
| Tid | item |
+-----+------+
| 11 | A |
| 11 | B |
| 12 | B |
| 12 | C |
| 13 | C |
| 13 | D |
| 13 | E |
| 14 | D |
| 14 | E |
| 15 | E |
| 21 | A |
| 21 | E |
+-----+------+
这是 table 的演练:
首先,我们检查所有 Tid 为 1 的项目,并创建 Tid 为 1n 的子组,其中 n 是一个计数器。
我们的 Tid 为 11 的第一个子组由项目 A、B 组成,因为最后一项和第一项之间的 deltaT =<2。下一组有 Tid 12 和项目 B、C。之后的组有 Tid 13 和项目 C、D、E,因为所有项目都在 2 秒的时间跨度内。这一直持续到 Tid 1 的最后一个项目。然后我们从 Tid 2 的组重新开始。
子组的新Tid编号可以是连续的(1...6),我选择这种编号只是为了表示与原来的关系table。
我正在查看 vertica 函数 LAG 和 Time_slice,但无法想出如何优雅地处理此类问题的方法。
这就是我的进展 - 它并没有回答你的问题,真的。但它可以构成一些指针:
WITH
-- your input
input(Tid,item,time_sec) AS (
SELECT 1,'A',1
UNION ALL SELECT 1,'B',2
UNION ALL SELECT 1,'C',4
UNION ALL SELECT 1,'D',5
UNION ALL SELECT 1,'E',6
UNION ALL SELECT 2,'A',5
UNION ALL SELECT 2,'E',5
)
-- end of your input, start your "real" WITH clause here
,
input_w_ts AS (
SELECT
*
, TIMESTAMPADD('SECOND',time_sec-1,TIMESTAMP '2000-01-01 00:00:00') AS ts
FROM input
)
SELECT
TS_LAST_VALUE(Tid) AS Tid
, item
, TS_LAST_VALUE(time_sec) AS time_sec
, tsr
FROM input_w_ts
TIMESERIES tsr AS '2 SECONDS' OVER (PARTITION BY item ORDER BY ts)
ORDER BY 1,4
;
Output:
Tid|item|time_sec|tsr
1|A | 1|2000-01-01 00:00:00
1|B | 2|2000-01-01 00:00:00
1|A | 1|2000-01-01 00:00:02
1|C | 4|2000-01-01 00:00:02
1|D | 5|2000-01-01 00:00:04
1|E | 6|2000-01-01 00:00:04
2|A | 5|2000-01-01 00:00:04
大家好:我在 vertica 数据库中有以下 table:
+-----+------+----------+
| Tid | item | time_sec |
+-----+------+----------+
| 1 | A | 1 |
| 1 | B | 2 |
| 1 | C | 4 |
| 1 | D | 5 |
| 1 | E | 6 |
| 2 | A | 5 |
| 2 | E | 5 |
+-----+------+----------+
我的目标是在时间 window deltaT 内创建新的项目组。这意味着第一个和最后一个项目的时间戳之间的差异小于或等于 deltaT。示例:如果 deltaT = 2 秒,我们将得到新的 table:
+-----+------+
| Tid | item |
+-----+------+
| 11 | A |
| 11 | B |
| 12 | B |
| 12 | C |
| 13 | C |
| 13 | D |
| 13 | E |
| 14 | D |
| 14 | E |
| 15 | E |
| 21 | A |
| 21 | E |
+-----+------+
这是 table 的演练: 首先,我们检查所有 Tid 为 1 的项目,并创建 Tid 为 1n 的子组,其中 n 是一个计数器。 我们的 Tid 为 11 的第一个子组由项目 A、B 组成,因为最后一项和第一项之间的 deltaT =<2。下一组有 Tid 12 和项目 B、C。之后的组有 Tid 13 和项目 C、D、E,因为所有项目都在 2 秒的时间跨度内。这一直持续到 Tid 1 的最后一个项目。然后我们从 Tid 2 的组重新开始。
子组的新Tid编号可以是连续的(1...6),我选择这种编号只是为了表示与原来的关系table。
我正在查看 vertica 函数 LAG 和 Time_slice,但无法想出如何优雅地处理此类问题的方法。
这就是我的进展 - 它并没有回答你的问题,真的。但它可以构成一些指针:
WITH
-- your input
input(Tid,item,time_sec) AS (
SELECT 1,'A',1
UNION ALL SELECT 1,'B',2
UNION ALL SELECT 1,'C',4
UNION ALL SELECT 1,'D',5
UNION ALL SELECT 1,'E',6
UNION ALL SELECT 2,'A',5
UNION ALL SELECT 2,'E',5
)
-- end of your input, start your "real" WITH clause here
,
input_w_ts AS (
SELECT
*
, TIMESTAMPADD('SECOND',time_sec-1,TIMESTAMP '2000-01-01 00:00:00') AS ts
FROM input
)
SELECT
TS_LAST_VALUE(Tid) AS Tid
, item
, TS_LAST_VALUE(time_sec) AS time_sec
, tsr
FROM input_w_ts
TIMESERIES tsr AS '2 SECONDS' OVER (PARTITION BY item ORDER BY ts)
ORDER BY 1,4
;
Output:
Tid|item|time_sec|tsr
1|A | 1|2000-01-01 00:00:00
1|B | 2|2000-01-01 00:00:00
1|A | 1|2000-01-01 00:00:02
1|C | 4|2000-01-01 00:00:02
1|D | 5|2000-01-01 00:00:04
1|E | 6|2000-01-01 00:00:04
2|A | 5|2000-01-01 00:00:04