SQL функция для запуска счетчика, который увеличивается при изменении флага? - PullRequest
0 голосов
/ 13 января 2020

У меня есть данные, которые выглядят как первые три столбца, и я хотел бы добавить четвертый столбец для Цикла, который равен нулю, когда Флаг равен нулю, и в противном случае подсчитывает вхождение этого флага для данного x, упорядоченного по дате. Я использую db2, и я не уверен, как изменить функцию row_number (), чтобы получить этот результат.

  name  date           Flag        Cycle
    x     2014            0          Null
    x     2015            0          Null
    x     2016            1          1
    x     2017            1          1
    x     2018            0          Null
    x     2019            1          2
    x     2020            0          Null
    x     2021            1          3 
    y     2014            0          Null
    y     2016            1          1
    y     2017            0          Null
    y     2018            1          2

Я ищу что-то, что ведет себя как функция Rank, но позволяет в ie - ранжирование на основе дубликатов в операторе разбиения, а не на порядок по.

Ответы [ 2 ]

2 голосов
/ 13 января 2020

Похоже на кумулятивную сумму:

select t.*,
       (case when flag = 1
             then sum(flag) over (partition by name order by date)
        end) as cycle_start
from t;

Предполагается, что флаг принимает только значения 0 и 1, как в данных примера. Его можно легко изменить, если флаг принимает другие значения, отличные от 0.

РЕДАКТИРОВАТЬ:

Исходя из вашего комментария, я неправильно понял проблему. Вы хотите идентифицировать смежные «группы» записей. Для этого определите группу, используя количество предыдущих значений NULL, а затем сделайте кумулятивную сумму:

select t.*,
       (case when flag = 1
             then dense_rank() over (partition by name order by grp)
        end) as cycle_start
from (select t.*,
             sum(1 - flag) over (partition by name order by date) as grp
      from t
     ) t
1 голос
/ 13 января 2020

Вы можете использовать lag() и окно sum():

select
    name,
    date,
    flag,
    case when flag = 1 
        then sum(cycle_start) over(partition by name order by date) 
    end cycle 
from (
    select
        t.*,
        case
            when lag(flag) over(partition by name order by date) = 0 and flag = 1
            then 1
        end cycle_start
    from mytable t
) t
order by name, date

Внутренний запрос обнаруживает начало цикла как переход от 0 к 1. Внешний запрос выполняет оконную сумму запуска цикла и отображает ее только при включенном флаге.

Демонстрация по БД Fiddlde :

NAME | DATE | FLAG | CYCLE
---: | ---: | ---: | ----:
   x | 2014 |    0 |  <em>null</em>
   x | 2015 |    0 |  <em>null</em>
   x | 2016 |    1 |     1
   x | 2017 |    1 |     1
   x | 2018 |    0 |  <em>null</em>
   x | 2019 |    1 |     2
   x | 2020 |    0 |  <em>null</em>
   x | 2021 |    1 |     3
   y | 2014 |    0 |  <em>null</em>
   y | 2016 |    1 |     1
   y | 2017 |    0 |  <em>null</em>
   y | 2018 |    1 |     2
...