postgresql - 如何在 postgres 中查询并发事件,即使用情况?
问题描述
从下面我的第一个事件表中,什么查询会给我我的第二个使用表?
开始 | 结尾 |
---|---|
08:42 | 08:47 |
08:44 | 08:50 |
开始 | 结尾 | 数数 |
---|---|---|
08:42 | 08:44 | 1 |
08:44 | 08:47 | 2 |
08:47 | 08:50 | 1 |
如果我应该创建任何索引来加快速度怎么办?
我经常需要的主要事情是峰值使用量和峰值使用时间(即上面的最大计数行),那么还有一种更快的方法来获得其中一个/两个吗?
此外,每秒查询是否更快(我可以想象如何做),例如:
时间 | 数数 |
---|---|
08:42 | 1 |
08:43 | 1 |
08:44 | 2 |
08:45 | 2 |
08:46 | 2 |
08:47 | 1 |
08:48 | 1 |
08:49 | 1 |
注意我的实际开始/结束时间是带时区的时间戳(6),我有数千条记录,但我希望我上面的例子有用。
解决方案
SELECT
t as start,
lead as "end",
sum as count
FROM (
SELECT
t,
lead(t) OVER (ORDER BY t), -- 2a
type,
SUM(type) OVER (ORDER BY t) -- 2b
FROM (
SELECT -- 1
start as t,
1 as type
FROM mytable
UNION
SELECT
stop,
-1 as type
FROM mytable
) s
) s
WHERE sum > 0 -- 3
- 将所有时间值放入一列。将值添加
1
到以前的start
值和-1
以前的end
值 - a) 将下一次值放入当前记录 b) 使用累计
SUM()
超过新添加的1
/-1
值。每个start
点增加计数,每个end
值减少它。这是你的预期count
- 无间隔地删除所有记录。
以上仅在您的边界不同时才能正常工作。如果您在同一时间点有间隔边界,则必须将其更改UNION
为(保持相同的值)并随后将此结果分组以从同一时间段的两个值UNION ALL
生成例如:-2
-1
SELECT
t as start,
lead as "end",
sum as count
FROM (
SELECT
t,
lead(t) OVER (ORDER BY t),
type,
SUM(type) OVER (ORDER BY t)
FROM (
SELECT
t,
SUM(type) AS type
FROM (
SELECT
start as t,
1 as type
FROM mytable
UNION ALL
SELECT
stop,
-1 as type
FROM mytable
) s
GROUP BY t
) s
) s
WHERE sum > 0