SQL: суммирование столбца, начинающегося со строки, сразу после двух последовательных «триггерных» значений в другом столбце - PullRequest
0 голосов
/ 20 марта 2019

Как сложить все значения после двух последовательных YES в столбце CONDITION_SATISFIED?

ID | CONDITION_SATISFIED | VALUE
--------------------------------
 1 | NO                  |   100
 2 | NO                  |   300
 3 | NO                  |   500
 4 | YES                 |   100
 5 | YES                 |   300
 6 | NO                  |   500 <-
 7 | NO                  |   100 <-
 8 | YES                 |   300 <-
 9 | NO                  |   500 <-
--------------------------------
                     SUM |  1400 

Примечание: дальнейшие вхождения YES / NO игнорируются после начала суммирования.

Я дошел до того, что смог создать два дополнительных столбца для столбца CONDITION_SATISFIED, например:

ID | CONDITION_SATISFIED | VALUE     RANK | REPEAT_COUNT
--------------------------------     -------------------
 1 | NO                  |   100        1 |            3
 2 | NO                  |   300        1 |            3 
 3 | NO                  |   500        1 |            3 
 4 | YES                 |   100        2 |            2 
 5 | YES                 |   300        2 |            2 
 6 | NO                  |   500        3 |            2 <- start from here
 7 | NO                  |   100        3 |            2 
 8 | YES                 |   300        4 |            1 
 9 | NO                  |   500        5 |            1
--------------------------------     -------------------

Но я не могу понять, как его получить.первый экземпляр REPEAT_COUNT >= 2 AND CONDITION_SATISFIED = 'YES', а затем начните суммирование сразу после 2-го YES (как указано).

Ответы [ 2 ]

1 голос
/ 20 марта 2019

Хммм. , , Вы можете получить первое, где два дачи используют lag():

select t.*
from (select t.*,
             lag(condition_satisfied) over (order by id) as prev_cs,
             lag(condition_satisfied, 2) over (order by id) as prev2_cs
      from t
     ) t
where prev2_cs = 'YES' and prev_cs = 'YES';

Тогда вы можете просто использовать это в запросе:

select t.*
from t join
     (select min(t.id) as id
      from (select t.*,
                   lag(condition_satisfied) over (order by id) as prev_cs,
                   lag(condition_satisfied, 2) over (order by id) as prev2_cs
            from t
           ) t
      where prev2_cs = 'YES' and prev_cs = 'YES'
     ) yy
     on t.id >= yy.id;
0 голосов
/ 20 марта 2019

Oracle 12c: сопоставление с образцом

with t1 (id, condition_satisfied, value) as (
select 1, 'NO' , 100 from dual union all
select 2, 'NO' , 300 from dual union all
select 3, 'NO' , 500 from dual union all
select 4, 'YES', 100 from dual union all
select 5, 'YES', 300 from dual union all
select 6, 'NO' , 500 from dual union all
select 7, 'NO' , 100 from dual union all
select 8, 'YES', 300 from dual union all
select 9, 'NO' , 500 from dual)
select sum(v_value) as sum_value
from t1
match_recognize(
order by id
measures s.value as v_value
all rows per match
pattern (yes{2} s+)
define
yes   as condition_satisfied = 'YES'
);

 SUM_VALUE
----------
      1400

Если у вас версия ниже 12, нет необходимости самостоятельно объединяться и генерировать / предотвращать дубликаты:

with s (id, condition_satisfied, value) as (
select 1, 'NO' , 100 from dual union all
select 2, 'NO' , 300 from dual union all
select 3, 'NO' , 500 from dual union all
select 4, 'YES', 100 from dual union all
select 5, 'YES', 300 from dual union all
select 6, 'NO' , 500 from dual union all
select 7, 'YES' , 100 from dual union all
select 8, 'YES', 300 from dual union all
select 9, 'NO' , 500 from dual)
select sum(value) sum_value
from
   (select s.*, min(first_id) over () min_id
    from
       (select s.*,
        case when condition_satisfied = 'YES' and condition_satisfied = lag(condition_satisfied) over (order by id) then id end first_id
        from s
       ) s
   )
where id > min_id;

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