0

My data is like shown in column "Original data". I would like to get results as shown in column "Result". Is there any way to do this with Oracle SQL functions? Oracle version is 12c Release 12.1.0.1.0.

Original data Result
0 0
0 0
1 1
1 2
1 3
0 0
0 0
0 0
0 0
1 1
1 2
1 3
1 4
1 5
1 6
0 0
0 0

Many thanks for any tips you might have.

1
  • 3
    How do you determine the order of Original data? Commented Jan 4, 2021 at 15:20

1 Answer 1

3

You must have a way to totally order the input rows. ("Total" ordering means "no ties".)

Other than that, you can do this easily with match_recognize, as shown below. In the output I included the ordering column (I assumed a numeric column, but it can be a date, etc. - whatever you can use to totally order the inputs) and I included both the original and the new values; if you only need the new values, you can control that in the select clause.

The input data in the with clause is there just for easy testing; you will need to remove it, and to use your actual table and column names in the query.

with
  sample_inputs (ord, val) as (
    select  1, 0 from dual union all
    select  2, 0 from dual union all
    select  3, 1 from dual union all
    select  4, 1 from dual union all
    select  5, 1 from dual union all
    select  6, 0 from dual union all
    select  7, 0 from dual union all
    select  8, 0 from dual union all
    select  9, 0 from dual union all
    select 10, 1 from dual union all
    select 11, 1 from dual union all
    select 12, 1 from dual union all
    select 13, 1 from dual union all
    select 14, 1 from dual union all
    select 15, 1 from dual union all
    select 16, 0 from dual union all
    select 17, 0 from dual
  )
select ord, val, new_val
from   sample_inputs
match_recognize (
  order by ord
  measures count(a.val) as new_val
  all rows per match
  pattern  ( a+ | b+ )
  define   a as val = 1, b as val = 0
);

OUTPUT:

       ORD        VAL    NEW_VAL
---------- ---------- ----------
         1          0          0
         2          0          0
         3          1          1
         4          1          2
         5          1          3
         6          0          0
         7          0          0
         8          0          0
         9          0          0
        10          1          1
        11          1          2
        12          1          3
        13          1          4
        14          1          5
        15          1          6
        16          0          0
        17          0          0

This assumes that your intent is to "count" the values (rather than, for example, "sum" them). If all the input values are 0 and 1, then it makes no difference. If you may also have other non-zero values (other than 1), and you must "sum" them instead of counting them, that's a simple modification to the query - use sum(val) in the measures clause. In both cases, with the all rows per match clause, the query will compute cumulative values (cumulative count, resp. cumulative sum).

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.