试图了解我该怎么做:
|id| timestamp | type |
|--|--------------------------|---------|
|11|2018-10-02 15:57:07.000000| open |
|11|2018-10-02 16:48:51.000000| closed |
|11|2018-10-05 08:59:27.000000| open |
|11|2018-10-05 09:59:18.000000| closed |
那
|id| open_ts | closed_ts |
|--|--------------------------|--------------------------|
|11|2018-10-02 15:57:07.000000|2018-10-02 16:48:51.000000|
|11|2018-10-05 08:59:27.000000|2018-10-05 09:59:18.000000|
我根据类型的条件进行了“自连接”。 这里有一个规则:“打开”之后应始终“关闭”。直到“关闭”它才能“打开”。 我最好的结果是:
|id| open_ts | closed_ts |
|--|--------------------------|--------------------------|
|11|2018-10-02 15:57:07.000000|2018-10-02 16:48:51.000000|
|11|2018-10-02 15:57:07.000000|2018-10-05 09:59:18.000000|
|11|2018-10-05 08:59:27.000000|2018-10-02 16:48:51.000000|
|11|2018-10-05 08:59:27.000000|2018-10-05 09:59:18.000000|
select z.id id, z.timestamp open_ts, o.timestamp closed_ts
from temp_event z
join temp_event o
on z.id=o.id
where z.type='open' and o.type='closed'
此外,我尝试在(id)*上使用distinct,但是我得到了错误的间隔值:
|id| open_ts | closed_ts |
|--|--------------------------|--------------------------|
|11|2018-10-02 15:57:07.000000|2018-10-02 16:48:51.000000|
|11|2018-10-05 08:59:27.000000|2018-10-02 16:48:51.000000|
附加表中的*。此ID在提供的表格中以两个ID的形式存在。
答案 0 :(得分:1)
您可以使用lead()
:
select id, timestamp as open_ts, closed_ts
from (select t.*,
lead(timestamp) filter (where type = 'closed') over (partition by id order by timestamp) as closed_ts
from t
) t
where type = 'open';
答案 1 :(得分:1)
使用窗口函数row_number()
来指定对:
with temp_rn as (
select *, row_number() over (partition by id, type order by timestamp) as rn
from temp_event
)
select t1.id, t1.timestamp as open_ts, t2.timestamp as close_ts
from temp_rn t1
join temp_rn t2
on t1.id = t2.id and t1.rn = t2.rn and t1.type > t2.type
id | open_ts | close_ts
----+---------------------+---------------------
11 | 2018-10-02 15:57:07 | 2018-10-02 16:48:51
11 | 2018-10-05 08:59:27 | 2018-10-05 09:59:18
(2 rows)