使用 SQL 中的两个时间戳列在 "point-in_time" 处生成计数
Using two timestamp columns in SQL to generate counts at a "point-in_time"
我有一个带有票证的 Postgres 数据库 table。每张票都有一个 'created_at' 时间戳和一个 'resolved_at' 时间戳。我最终想创建一个时间序列可视化来跟踪一段时间内 'unresolved' 票的数量。
例如,我想查看过去 24 小时,看看每个小时结束时有多少工单未解决,即 created_at < "point-in-time" AND resolved_at > "point-in-time".
我不知道我是如何开始查询这类信息的。我如何在查询中引用多个 "point-in-time values"?
示例设置:
CREATE TABLE tickets (
id int,
created_at timestamp,
resolved_at timestamp
);
INSERT INTO tickets VALUES
(1, '2019-10-01 01:30:00'::timestamp, '2019-10-01 05:45:00'::timestamp),
(2, '2019-10-01 02:30:00'::timestamp, '2019-10-01 05:45:00'::timestamp),
(3, '2019-10-01 03:30:00'::timestamp, '2019-10-01 05:45:00'::timestamp),
(4, '2019-10-01 04:30:00'::timestamp, '2019-10-01 05:45:00'::timestamp),
(5, '2019-10-01 05:30:00'::timestamp, '2019-10-01 05:45:00'::timestamp);
我可以从这些数据中看出,在 01:00 我们有 0 个未解决,在 02:00 1 个未解决(票 1),...,05:00 4 个未解决, 06:00 0 未解决(所有工单已由 05:45 解决)。我不确定如何查询此信息
我们将分三个逻辑步骤找到解决方案。一、及时获取一系列事件:
select created_at as event_time, 1 as change
from tickets
union all
select resolved_at, -1
from tickets
order by 1
event_time | change
---------------------+--------
2019-10-01 01:30:00 | 1
2019-10-01 02:30:00 | 1
2019-10-01 03:30:00 | 1
2019-10-01 04:30:00 | 1
2019-10-01 05:30:00 | 1
2019-10-01 05:45:00 | -1
2019-10-01 05:45:00 | -1
2019-10-01 05:45:00 | -1
2019-10-01 05:45:00 | -1
2019-10-01 05:45:00 | -1
(10 rows)
接下来,将时间四舍五入为整小时并对变化求和:
select
date_trunc('hour', event_time+ interval '1h') as time_point,
sum(change) as change
from (
select created_at as event_time, 1 as change
from tickets
union all
select resolved_at, -1
from tickets
) s
group by 1
order by 1
time_point | change
---------------------+--------
2019-10-01 02:00:00 | 1
2019-10-01 03:00:00 | 1
2019-10-01 04:00:00 | 1
2019-10-01 05:00:00 | 1
2019-10-01 06:00:00 | -4
(5 rows)
最后得到连续周期变化的累计和:
select
time_point,
sum(change) over (order by time_point) as unresolved
from (
select
date_trunc('hour', event_time+ interval '1h') as time_point,
sum(change) as change
from (
select created_at as event_time, 1 as change
from tickets
union all
select resolved_at, -1
from tickets
) s
group by 1
) s
order by 1
time_point | unresolved
---------------------+------------
2019-10-01 02:00:00 | 1
2019-10-01 03:00:00 | 2
2019-10-01 04:00:00 | 3
2019-10-01 05:00:00 | 4
2019-10-01 06:00:00 | 0
(5 rows)
在最终查询中,您可以使用时间戳系列(由函数生成)来避免间隙:
select
time_point,
coalesce(sum(change) over (order by time_point), 0) as unresolved
from
generate_series(timestamp '2019-10-01 01:00', '2019-10-01 06:00', interval '1h') as time_point
left join (
select
date_trunc('hour', event_time+ interval '1h') as time_point,
sum(change) as change
from (
select created_at as event_time, 1 as change
from tickets
union all
select resolved_at, -1
from tickets
) s
group by 1
) s using(time_point)
order by 1
我有一个带有票证的 Postgres 数据库 table。每张票都有一个 'created_at' 时间戳和一个 'resolved_at' 时间戳。我最终想创建一个时间序列可视化来跟踪一段时间内 'unresolved' 票的数量。
例如,我想查看过去 24 小时,看看每个小时结束时有多少工单未解决,即 created_at < "point-in-time" AND resolved_at > "point-in-time".
我不知道我是如何开始查询这类信息的。我如何在查询中引用多个 "point-in-time values"?
示例设置:
CREATE TABLE tickets (
id int,
created_at timestamp,
resolved_at timestamp
);
INSERT INTO tickets VALUES
(1, '2019-10-01 01:30:00'::timestamp, '2019-10-01 05:45:00'::timestamp),
(2, '2019-10-01 02:30:00'::timestamp, '2019-10-01 05:45:00'::timestamp),
(3, '2019-10-01 03:30:00'::timestamp, '2019-10-01 05:45:00'::timestamp),
(4, '2019-10-01 04:30:00'::timestamp, '2019-10-01 05:45:00'::timestamp),
(5, '2019-10-01 05:30:00'::timestamp, '2019-10-01 05:45:00'::timestamp);
我可以从这些数据中看出,在 01:00 我们有 0 个未解决,在 02:00 1 个未解决(票 1),...,05:00 4 个未解决, 06:00 0 未解决(所有工单已由 05:45 解决)。我不确定如何查询此信息
我们将分三个逻辑步骤找到解决方案。一、及时获取一系列事件:
select created_at as event_time, 1 as change
from tickets
union all
select resolved_at, -1
from tickets
order by 1
event_time | change
---------------------+--------
2019-10-01 01:30:00 | 1
2019-10-01 02:30:00 | 1
2019-10-01 03:30:00 | 1
2019-10-01 04:30:00 | 1
2019-10-01 05:30:00 | 1
2019-10-01 05:45:00 | -1
2019-10-01 05:45:00 | -1
2019-10-01 05:45:00 | -1
2019-10-01 05:45:00 | -1
2019-10-01 05:45:00 | -1
(10 rows)
接下来,将时间四舍五入为整小时并对变化求和:
select
date_trunc('hour', event_time+ interval '1h') as time_point,
sum(change) as change
from (
select created_at as event_time, 1 as change
from tickets
union all
select resolved_at, -1
from tickets
) s
group by 1
order by 1
time_point | change
---------------------+--------
2019-10-01 02:00:00 | 1
2019-10-01 03:00:00 | 1
2019-10-01 04:00:00 | 1
2019-10-01 05:00:00 | 1
2019-10-01 06:00:00 | -4
(5 rows)
最后得到连续周期变化的累计和:
select
time_point,
sum(change) over (order by time_point) as unresolved
from (
select
date_trunc('hour', event_time+ interval '1h') as time_point,
sum(change) as change
from (
select created_at as event_time, 1 as change
from tickets
union all
select resolved_at, -1
from tickets
) s
group by 1
) s
order by 1
time_point | unresolved
---------------------+------------
2019-10-01 02:00:00 | 1
2019-10-01 03:00:00 | 2
2019-10-01 04:00:00 | 3
2019-10-01 05:00:00 | 4
2019-10-01 06:00:00 | 0
(5 rows)
在最终查询中,您可以使用时间戳系列(由函数生成)来避免间隙:
select
time_point,
coalesce(sum(change) over (order by time_point), 0) as unresolved
from
generate_series(timestamp '2019-10-01 01:00', '2019-10-01 06:00', interval '1h') as time_point
left join (
select
date_trunc('hour', event_time+ interval '1h') as time_point,
sum(change) as change
from (
select created_at as event_time, 1 as change
from tickets
union all
select resolved_at, -1
from tickets
) s
group by 1
) s using(time_point)
order by 1