Группировка периодов дат на основе двух отдельных рейтингов / групп - PullRequest
0 голосов
/ 30 января 2019

Привет всем, извините за мой плохо сформулированный заголовок. Я не уверен, как правильно сформулировать то, что мне нужно.Но я постараюсь объяснить это лучше ниже:

У меня есть набор данных, который выглядит следующим образом:

DECLARE @TestDATA TABLE (PERSON_ID int, START_DATE date, END_DATE date,SERVICE_RANK int)

INSERT INTO @TestDATA 
VALUES 
(123, '2018-01-31', '2018-02-14', 7), 
(123, '2018-03-28', '2018-04-11', 4), 
(123, '2018-04-12', '2018-04-30', 4), 
(123, '2018-05-25', '2018-06-08', 7), 
(123, '2018-06-08', '2018-06-15', 7), 
(123, '2018-06-19', '2018-06-26', 7), 
(123, '2018-06-26', '2018-09-28', 4), 
(123, '2018-10-10', '2018-11-07', 7), 
(123, '2018-11-27', '2018-12-11', 7), 
(123, '2018-12-11', '2018-12-24', 7)

, который показывает диапазон дат и «ранг обслуживания» для каждого человека (естьтолько один человек в этом примере, но в базе данных десятки тысяч)

Где для каждого person_id и каждого service_rank я хотел бы сгруппировать периоды дат, чтобы определить, сколько у них было разных периодов.Так что в приведенном выше примере это то, что я искал бы:

PERSON ID, START_DATE,  END_DATE,  SERVICE_RANK, SERVICE_PERIOD    
    123    2018-01-31   2018-02-14     7             1
    123    2018-03-28   2018-04-11     4             2
    123    2018-04-12   2018-04-30     4             2
    123    2018-05-25   2018-06-08     7             3
    123    2018-06-08   2018-06-15     7             3
    123    2018-06-19   2018-06-26     7             3
    123    2018-06-26   2018-09-28     4             4
    123    2018-10-10   2018-11-07     7             5
    123    2018-11-27   2018-12-11     7             5
    123    2018-12-11   2018-12-24     7             5  

Я пробовал row_number, rank, dens_rank и даже попробовал ужасный CURSOR FOR, но я не могу заставить что-либо работать как оконныйфункции видят ранги сервисов одинаковыми, поэтому в приведенном выше примере они увидят два ранга сервисов, когда их фактически 5, они просто имеют одинаковую нумерацию.

Также в наборе данных не каждый человек будет прыгать с одного service_rankк другому и обратно.Они могут переходить от одного к другому (например, 4 -> 7) и оставаться там, или они могут иметь только один service_rank на несколько строк.

Любые идеи ??

1 Ответ

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

Это проблема пробелов и островков.Для этой цели используется один метод lag() и совокупная сумма:

select t.*,
       sum(case when prev_service_rank = service_rank then 0 else 1 end) over (partition by person_id order by start_date) as service_period
from (select t.*,
             lag(service_rank) over (partition by person_id order by start_date) as prev_service_rank
      from t
     ) t;
...