Выбрать пару значений строк по определенному правилу для других столбцов - PullRequest
0 голосов
/ 11 января 2019

Пытаясь понять, как я могу это сделать:


|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'

Кроме того, я пытался использовать разные on (id) *, но получил неверное значение интервала:

|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|

* из дополнительной таблицы. Этот идентификатор существует в двух экземплярах для одного идентификатора в представленной таблице.

Ответы [ 2 ]

0 голосов
/ 11 января 2019

Используйте функцию окна 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)    
0 голосов
/ 11 января 2019

Вы можете использовать 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';
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...