Время, проведенное в нескольких (одном и том же) месте - функция окна, может быть? - PullRequest
0 голосов
/ 05 марта 2019

Каждый цвет - это локация. Это упорядочено по дате начала и должно оставаться таким, чтобы найти первое местоположение, второе и т. Д. Местоположение может появляться более одного раза по разным причинам. Мне нужна самая ранняя дата начала и последняя дата окончания для каждого "окна" или ID, LOC. Надеемся, что приведенный ниже пример хорошо читается и проясняет это Я работаю в SQL Server. Можно сделать в Oracle. Я пробовал разные оконные функции ... first_value, last_value, lead, lag, разделил по-разному с разными комбинациями и не повезло. Фактические данные будут иметь много разных идентификаторов, поэтому они должны быть частью раздела. Спасибо за любую помощь.

Это пример данных:

+----------------------------------------------------+
|ID   |LOC   |START              |END                |
+----------------------------------------------------+
|45334|RED   |2015-08-26 17:26:21|2015-08-26 20:17:00|
|45334|GREEN |2015-08-26 20:17:50|2015-08-30 21:01:00|
|45334|GREEN |2015-08-30 21:01:49|2015-09-02 15:19:00|
|45334|YELLOW|2015-09-02 15:19:33|2015-09-02 21:46:00|
|45334|GREEN |2015-09-02 21:46:36|2015-09-05 19:48:00|
|45334|BLUE  |2015-09-05 19:48:26|2015-09-05 20:33:00|
|45334|YELLOW|2015-09-05 20:33:11|2015-09-05 21:27:00|
|45334|BLACK |2015-09-05 21:27:38|2015-09-07 16:48:09|
|45334|BLACK |2015-09-07 16:48:09|2015-09-08 18:30:00|
|45334|GREEN |2015-09-08 18:35:13|2015-09-10 11:15:23|
|45334|GREEN |2015-09-10 11:15:23|2015-09-10 20:32:00|
|45334|GREEN |2015-09-10 20:32:57|2015-09-16 15:22:58|
|45334|GREEN |2015-09-16 15:22:58|2015-09-17 14:02:00|
|45334|YELLOW|2015-09-17 14:02:28|2015-09-17 17:04:00|
|45334|BLACK |2015-09-17 17:04:25|2015-09-18 11:36:03|
|45334|BLACK |2015-09-18 11:36:03|2015-09-18 21:48:00|
|45334|GREEN |2015-09-18 21:49:05|2015-09-21 11:22:29|
|45334|GREEN |2015-09-21 11:22:29|2015-09-21 18:54:00|
|45334|GREEN |2015-09-21 18:54:50|2015-09-23 13:39:00|
|45334|GREEN |2015-09-23 13:39:25|2015-09-23 16:12:00|
|45334|GREEN |2015-09-23 16:12:00|2015-09-23 16:25:00|
|45334|GREEN |2015-09-23 16:25:37|2015-10-02 15:13:00|
|45334|GREEN |2015-10-02 15:13:00|2015-10-02 15:13:00|
|45334|GREEN |2015-10-02 15:13:00|2015-10-02 15:13:00|
|45334|GREEN |2015-10-02 15:13:00|2015-10-02 15:13:00|
|45334|GREEN |2015-10-02 15:13:00|2015-10-02 15:13:00|
|45334|GREEN |2015-10-02 15:13:00|2015-10-02 15:13:00|
|45334|GREEN |2015-10-02 15:13:00|2015-10-02 15:13:00|
+----------------------------------------------------+

Вот как это должно выглядеть:

+----------------------------------------------------+
|ID   |LOC   |START              |END                |
+----------------------------------------------------+
|45334|RED   |2015-08-26 17:26:21|2015-08-26 20:17:00|
|45334|GREEN |2015-08-26 20:17:50|2015-09-02 15:19:00|
|45334|YELLOW|2015-09-02 15:19:33|2015-09-02 21:46:00|
|45334|GREEN |2015-09-02 21:46:36|2015-09-05 19:48:00|
|45334|BLUE  |2015-09-05 19:48:26|2015-09-05 20:33:00|
|45334|YELLOW|2015-09-05 20:33:11|2015-09-05 21:27:00|
|45334|BLACK |2015-09-05 21:27:38|2015-09-08 18:30:00|
|45334|GREEN |2015-09-08 18:35:13|2015-09-17 14:02:00|
|45334|YELLOW|2015-09-17 14:02:28|2015-09-17 17:04:00|
|45334|BLACK |2015-09-17 17:04:25|2015-09-18 21:48:00|
|45334|GREEN |2015-09-18 21:49:05|2015-10-02 15:13:00|
+----------------------------------------------------+

Ответы [ 2 ]

0 голосов
/ 05 марта 2019

Вы также можете использовать Табибитозан :

select id,
       loc,
       to_char(min(start_), 'yyyy-mm-dd hh24:mi:ss') grp_start_time,
       to_char(max(end_), 'yyyy-mm-dd hh24:mi:ss') grp_end_time
from   (select t.*,
               row_number() over (partition by id order by start_, ROWNUM)
                 - row_number() over (partition by id, loc order by start_, ROWNUM) grp
        from t)
group by id, loc, grp

dbfiddle

N.B. Мне пришлось добавить rownum в порядок с помощью аналитических функций row_number(), потому что у вас есть строки в ваших данных выборки, которые имеют одинаковое время начала и окончания. Если время начала все разные по строкам для идентификатора и loc, вам не понадобится rownum в порядке по.

На вашем месте, я бы попробовал оба решения и выяснил, какое из них более эффективно для ваших данных и т. Д. имеет преимущество.)

0 голосов
/ 05 марта 2019

Назначить флаг как 1 при изменении местоположения.Используйте sum(flag) over (...) для создания столбца группировки.Наконец, группируем данные:

select id, min(loc), min(start_), max(end_)
  from (
    select a.*, sum(flag) over(order by start_) grp
      from (select t.*, case when loc <> lag(loc) over (order by start_) 
                             then 1 else 0 end flag from t) a )
  group by id, grp

Демоверсия dbfiddle

Протестировано в Oracle.Добавьте partition by id в окончательный код.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...