SQL группировка данных с учетом последовательности дат - PullRequest
0 голосов
/ 20 февраля 2020

Я пытаюсь сгруппировать отдельные строки, которые могут быть разбиты другой группой. Если они сломаны, я хочу, чтобы они сгруппировались отдельно.

Итак, у меня есть:

Col1 | Col2
---------------------
| Y  |01/JAN/2012
| Y  |01/FEB/2012
| N  |01/MAR/2012
| Y  |01/APR/2012
| Y  |01/MAY/2012

Я хочу получить результат:

|col1|col2       |GRP
---------------------
| Y  |01/JAN/2012|1
| Y  |01/FEB/2012|1
| N  |01/MAR/2012|2
| Y  |01/APR/2012|3
| Y  |01/MAY/2012|3

Как мне добиться это?

Моя текущая попытка такая:

select
    Col1,
    Col2,
    dense_rank() over (partition by Col1 order by Col2 asc) as grp  
from
    myTABLE
;

, но она объединяет все Y и дает мне порядковый номер, подобный этому:

|col1|col2       |GRP
---------------------
| Y  |01/JAN/2012|1
| Y  |01/FEB/2012|2
| N  |01/MAR/2012|1
| Y  |01/APR/2012|3
| Y  |01/MAY/2012|4

1 Ответ

1 голос
/ 20 февраля 2020

Это форма проблемы пробелов и островков. Я бы порекомендовал использовать разность номеров строк для определения "островков", а затем row_number():

select t.*, dense_rank() over (order by grp) as grp
from (select t.*,
             min(col2) over (partition by col1, seqnum - seqnum_2) as grp
      from (select t.*,
                   row_number() over (order by col2) as seqnum,
                   row_number() over (partition by col1 order by col2) as seqnum_2
            from t
           ) t
     ) t
order by col2;

На самом деле более простой способ - использовать lag() и совокупную сумму:

select t.*,
       sum(case when col1 = prev_col1 then 0 else 1 end) over (order by col2) as grp
from (select t.*, lag(col1) over (partition by col2) as prev_col1
      from t
     ) t
...