我想追溯具有相同属性且时间戳与行时间戳最多相差一小时的行数。
举个例子,给定表格:
时间戳 | ID |
---|---|
2021-04-17 01:51:44 | A |
2021-04-17 01:58:43 | A |
2021-04-17 02:01:32 | B |
2021-04-17 02:15:44 | A |
2021-04-17 02:57:44 | A |
2021-04-17 02:59:44 | B |
2021-04-17 03:15:44 | B |
2021-04-17 03:27:44 | A |
2021-04-17 03:31:44 | A |
2021-04-17 03:45:44 | B |
2021-04-17 03:52:44 | B |
2021-04-17 04:01:44 | B |
2021-04-17 04:23:44 | A |
我希望查询返回如下内容:
时间戳 | ID | 前一小时ID的出现次数 |
---|---|---|
2021-04-17 01:51:44 | A | 1 |
2021-04-17 01:58:43 | A | 2 |
2021-04-17 02:01:32 | B | 1 |
2021-04-17 02:15:44 | A | 3 |
2021-04-17 02:57:44 | A | 3 |
2021-04-17 02:59:44 | B | 2 |
2021-04-17 03:15:44 | B | 2 |
2021-04-17 03:27:44 | A | 2 |
2021-04-17 03:31:44 | A | 3 |
2021-04-17 03:45:44 | B | 3 |
2021-04-17 03:52:44 | B | 4 |
2021-04-17 04:01:44 | B | 4 |
2021-04-17 04:23:44 | A | 3 |
我想单独加入表,或者使用分区作为替代方案,但没有达到我想要的目的。
提前致谢
答案 0 :(得分:1)
您可以使用窗口函数:
COUNT(*) OVER (
PARTITION BY id
ORDER BY ts
RANGE BETWEEN INTERVAL '1' HOUR PRECEDING AND CURRENT ROW)
从概念上讲,它的作用是:
id
的所有行ts
(升序)对行进行排序ts
在行的 ts
之前 1 小时和行的 ts
之间的所有行这是一个完整的例子:
WITH t(ts, id) AS (
VALUES
(TIMESTAMP '2021-04-17 01:51:44', 'A'),
(TIMESTAMP '2021-04-17 01:58:43', 'A'),
(TIMESTAMP '2021-04-17 02:01:32', 'B'),
(TIMESTAMP '2021-04-17 02:15:44', 'A'),
(TIMESTAMP '2021-04-17 02:57:44', 'A'),
(TIMESTAMP '2021-04-17 02:59:44', 'B'),
(TIMESTAMP '2021-04-17 03:15:44', 'B'),
(TIMESTAMP '2021-04-17 03:27:44', 'A'),
(TIMESTAMP '2021-04-17 03:31:44', 'A'),
(TIMESTAMP '2021-04-17 03:45:44', 'B'),
(TIMESTAMP '2021-04-17 03:52:44', 'B'),
(TIMESTAMP '2021-04-17 04:01:44', 'B'),
(TIMESTAMP '2021-04-17 04:23:44', 'A')
)
SELECT ts,
id,
COUNT(*) OVER (
PARTITION BY id
ORDER BY ts
RANGE BETWEEN INTERVAL '1' HOUR PRECEDING AND CURRENT ROW)
FROM t
ORDER BY ts
有关 RANGE 窗口框架如何工作的说明,请参阅 this blog post。