【发布时间】:2014-03-28 14:14:04
【问题描述】:
(PostgreSQL 9.3) 我有一个“事件”表,其中包含数百万个复杂事件,存储为设备接收到的。例如目的:
+-----------+-------+
| Timestamp | Event |
+-----------+-------+
| 1 | A |
| 2 | A |
| 2 | B |
| 3 | B |
| 10 | A |
| 11 | A |
| 11 | 0 |
| 11 | C |
| 12 | A |
+-----------+-------+
在这种情况下,我有四种不同类型的事件:A、B、C 和 0。我想做的是对它们进行索引,以便我可以为每个事件设置开始/停止时间戳。停止条件是:在给定的时间戳不再报告事件,或者甚至出现“0”,清除所有事件。最终输出:
+------+----+-------+
| From | To | Event |
+------+----+-------+
| 1 | 3 | A |
| 2 | 10 | B |
| 10 | 11 | A |
| 11 | 11 | C |
| 12 | | A |
+------+----+-------+
在这种情况下,A 在 1 时提出,并在 3 时清除,因为此时不再报告。出于类似的原因,B 在 2 时被加注,在 10 时被清除。 A 在 10 时再次加注,并在 11 时通过 0 事件清除(尽管当时也有报道!)。 C 在 11 提出并同时清除(需要进行一些排序以在同一时间戳处理 0)。最后,A 在 12 时再次引发,并且当前处于活动状态,因此它得到一个 NULL 结束时间戳。
我确实有一些可行的方法,但它需要大量 CTE,因此无法很好地扩展数百万条记录。我一直在尝试 LATERAL(效果很好),我愿意接受任何 9.3 特定的建议。对于这个问题,“事件”本身也被大大简化了,实际上它是一组复杂的列。 Window-functions 也可能在这里应用。
【问题讨论】:
-
您的第一个示例条目看起来有误,它应该是“to 3”而不是“to 2”。它与所有其他的不一致。
-
现在没时间写一个正确的答案,但你看看窗口函数是对的。测试
event = lag(event) OVER (ORDER BY timestamp);这可以让您检测发生变化的边缘。顺便说一句,Stack Overflow 上有很多类似的问题,人们希望生成一个结果集,其中边缘的连续值系列发生变化;找到它们可能有些棘手。 -
实际上我在第一个索引事件中没有看到“to 2”?但是感谢您查看我的请求 - 我希望您或 Erwin 可以将我推向正确的方向。 Here's a similar question 但不知何故我不知道如何在这里应用相同的逻辑。
标签: sql postgresql window-functions