如果我在PostgreSQL 10.5中有一个带有以下条目的表session_logs
:
| id | session_id | recorded_at | powered | camera_blocked |
| --- | ---------- | ------------------------ | ------- | -------------- |
| 1 | 2 | 2019-06-26T13:40:00.000Z | true | false |
| 2 | 2 | 2019-06-26T13:45:00.000Z | false | false |
| 3 | 2 | 2019-06-26T13:50:00.000Z | false | true |
| 4 | 2 | 2019-06-26T13:55:00.000Z | false | false |
| 5 | 6 | 2019-06-26T13:45:00.000Z | true | false |
| 6 | 6 | 2019-06-26T13:50:00.000Z | false | false |
| 7 | 6 | 2019-06-26T13:55:00.000Z | false | true |
| 8 | 6 | 2019-06-26T14:00:00.000Z | false | false |
---
我想编写一个查询,该查询将给我以下结果
session_id started_at ended_at power_dur battery_dur camera_blocked_dur
--------------------------------------------------------------------------------------
2 2019-06-26 13:40:00 2019-06-26 13:55:00 5 10 5
6 2019-06-26 13:45:00 2019-06-26 14:00:00 5 10 5
如何编写一个查询,该查询在按session_id
分组时可以正确地对这些值求和?我有以下内容,但无法正确分组:
with session_log_lead as (
select sl.*, lead(recorded_at) over (order by recorded_at) as next_recorded_at
from session_logs as sl
)
select session_id, min(recorded_at) as session_start, max(recorded_at) as session_end,
sum(next_recorded_at - recorded_at) filter (where powered) as powered_duration,
sum(next_recorded_at - recorded_at) filter (where powered is false) as battery_duration,
sum(next_recorded_at - recorded_at) filter (where camera_blocked) as camera_blocked_duration
from session_log_lead
group by session_id
DB Fiddle:https://www.db-fiddle.com/f/7oC2w76QKuS5R4BapiqExW/1
答案 0 :(得分:1)
只需在窗口函数中添加一个PARTITION BY
即可通过每个 session_id 进行计算:
with session_log_lead as (
select sl.*, lead(recorded_at) over (partition by session_id order by recorded_at) as next_recorded_at
from session_logs as sl
)
select session_id,
min(recorded_at) as session_start,
max(recorded_at) as session_end,
sum(next_recorded_at - recorded_at) filter (where powered) as powered_duration,
sum(next_recorded_at - recorded_at) filter (where powered is false) as battery_duration,
sum(next_recorded_at - recorded_at) filter (where camera_blocked) as camera_blocked_duration
from session_log_lead
group by session_id
order by session_id;
另外,对于分钟的整数值,将EXTRACT(MINUTES FROM ...)
添加到聚合中:
EXTRACT(MINUTES FROM sum(next_recorded_at - recorded_at) filter (where powered)) as powered_duration,
EXTRACT(MINUTES FROM sum(next_recorded_at - recorded_at) filter (where powered is false)) as battery_duration,
EXTRACT(MINUTES FROM sum(next_recorded_at - recorded_at) filter (where camera_blocked)) as camera_blocked_duration