Как сгруппировать порядок данных по непрерывной временной шкале без неуникального идентификатора - PullRequest
1 голос
/ 19 сентября 2019

У меня есть данные, которые показывают, по дате, какие свойства элемента были активными.Например, в день 2 было активным только свойство с идентификатором 1, а в день 4 также было активировано другое свойство с идентификатором 2.Что мне нужно показать, так это то, как долго каждая комбинация свойств была активной.

См. Код.Я новичок в Oracle SQL и знаю, что хочу делать, но не знаю, какие функции использовать.Также я не знаю, что искать.У кода есть 2 разных подхода.Оба дают один и тот же результат, который не является неправильным, но также не тем, что я хочу.

with mydata as (    
  SELECT
    DECODE(rownum,
      1,to_date('19.09.2019'), 2,to_date('20.09.2019'), 3,to_date('21.09.2019'),
      4,to_date('22.09.2019'), 5,to_date('23.09.2019'), 6,to_date('24.09.2019'),
      7,to_date('25.09.2019'), 8,to_date('26.09.2019'), 9,to_date('27.09.2019'),
      10,to_date('28.09.2019'), 11,to_date('29.09.2019'), 12,to_date('30.09.2019'),
      13,to_date('01.10.2019'), 14,to_date('02.10.2019'), 15,to_date('03.10.2019'),
      16,to_date('04.10.2019'), 17,to_date('05.10.2019'), 18,to_date('06.10.2019'),
      19,to_date('07.10.2019'), 20,to_date('08.10.2019'), 21,to_date('09.10.2019'),
      22,to_date('10.10.2019'), 23,to_date('11.10.2019'), 24,to_date('12.10.2019'),
      25,to_date('13.10.2019')
    ) AS check_date,
    DECODE(rownum,
      1,'1', 2,'1', 3,'1', 4,'1;2', 5,'1;2', 6,'1;2', 7,'1', 8,'1', 9,'1;3',
      10,'1;3', 11,'1;3', 12,'3', 13,'3', 14,'3', 15,'4', 16,'4', 17,'4;5',
      18,'4;5', 19,'4;5', 20,'4', 21,'4', 22,'4', 23,'6', 24,'6', 25,'6'
    ) AS id_list
  FROM dual
  CONNECT BY level <= 25
)

-- select * from mydata;
-- select id_list, min(check_date) as valid_from, max(check_date) as valid_to 
-- from mydata group by id_list order by 2;

select 
  id_list, 
  min(valid_from), 
  max(valid_to) 
from (
  select id_list,
    min(check_date) over (
      partition by id_list 
      ORDER BY id_list 
      ROWS BETWEEN 0 PRECEDING AND UNBOUNDED FOLLOWING
    ) as valid_from,
    max(check_date) over (
      partition by id_list 
      ORDER BY id_list 
      ROWS BETWEEN 0 PRECEDING AND UNBOUNDED FOLLOWING
    ) as valid_to
  from mydata 
  order by 2
) 
group by id_list 
order by 2;

Результат таков:

id_list     valid_from              valid_to
1           19.09.2019 00:00:00     26.09.2019 00:00:00
1;2         22.09.2019 00:00:00     24.09.2019 00:00:00
1;3         27.09.2019 00:00:00     29.09.2019 00:00:00
3           30.09.2019 00:00:00     02.10.2019 00:00:00
4           03.10.2019 00:00:00     10.10.2019 00:00:00
4;5         05.10.2019 00:00:00     07.10.2019 00:00:00
6           11.10.2019 00:00:00     13.10.2019 00:00:00

Что я хочу: первая строка вывода должна иметьVALID_TO date 21.09.2019 потому что с 22.9.2019 действует следующая строка / комбинация.По сути, я не знаю, как справиться с перекрытием.

1 Ответ

1 голос
/ 19 сентября 2019

Это вариант проблемы разрывов и островков.Вы можете сравнить ранг записей по check_date повторениям их ранга в id_list разделах, чтобы решить, к какой группе они принадлежат.

Рассмотрим:

SELECT 
    id_list, 
    MIN(check_date) valid_from, 
    MAX(check_date) valid_to
FROM (
    SELECT
        id_list,
        check_date,
        ROW_NUMBER() OVER(ORDER BY check_date) rn1,
        ROW_NUMBER() OVER(PARTITION BY id_list ORDER BY check_date) rn2
    FROM mydata
) x 
GROUP BY id_list, rn1 - rn2
ORDER BY 2

Это демонстрация в DB Fiddle с вашими примерами возвращаемых данных:

ID_LIST | VALID_FROM | VALID_TO 
:------ | :--------- | :--------
1       | 19-SEP-19  | 21-SEP-19
1;2     | 22-SEP-19  | 24-SEP-19
1       | 25-SEP-19  | 26-SEP-19
1;3     | 27-SEP-19  | 29-SEP-19
3       | 30-SEP-19  | 02-OCT-19
4       | 03-OCT-19  | 04-OCT-19
4;5     | 05-OCT-19  | 07-OCT-19
4       | 08-OCT-19  | 10-OCT-19
6       | 11-OCT-19  | 13-OCT-19
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...