如何在Oracle SQL中有条件地累积值?

时间:2017-04-30 21:57:19

标签: sql oracle

我有一个列'C1',我希望通过在C1 = 1时累加(1,2,3,..)来计算另一列desired_output,但是当C1 =时,它会恢复为零0,当C1 = 1时再次开始向上计数(1,2,3,..)。代码如下:

    CREATE TABLE table1 (nr, id, int,c1 int,desired_output int);
    INSERT INTO table1 (nr, id, c1, desired_output) VALUES (1,1,1,1);
    INSERT INTO table1 (nr, id, c1, desired_output) VALUES (1,2,1,2);
    INSERT INTO table1 (nr, id, c1, desired_output) VALUES (1,3,0,0);
    INSERT INTO table1 (nr, id, c1, desired_output) VALUES (1,4,1,1);
    INSERT INTO table1 (nr, id, c1, desired_output) VALUES (1,5,0,0);
    INSERT INTO table1 (nr, id, c1, desired_output) VALUES (1,6,1,1);
    INSERT INTO table1 (nr, id, c1, desired_output) VALUES (1,7,1,2);
    INSERT INTO table1 (nr, id, c1, desired_output) VALUES (1,8,1,3);
    INSERT INTO table1 (nr, id, c1, desired_output) VALUES (1,9,1,4);
    INSERT INTO table1 (nr, id, c1, desired_output) VALUES (1,10,0,0);
    INSERT INTO table1 (nr, id, c1, desired_output) VALUES (1,11,1,1);
    INSERT INTO table1 (nr, id, c1, desired_output) VALUES (1,12,1,2);
    INSERT INTO table1 (nr, id, c1, desired_output) VALUES (1,13,1,3);
    INSERT INTO table1 (nr, id, c1, desired_output) VALUES (1,14,0,0);
    INSERT INTO table1 (nr, id, c1, desired_output) VALUES (1,15,1,1);

我已尝试过代码段(以及其他各种微笑代码段)

    SELECT A.*, SUM(CASE WHEN C1 = 1 THEN 1 END) OVER 
    (PARTITION BY NR ORDER BY ROWNUM) AS OUTPUT_2
    FROM TABLE1 A;

但这仅占技巧的一半,因为当C1 = 0时,OUTPUT_2的值不会恢复为零。

任何想法如何解决这个问题?

2 个答案:

答案 0 :(得分:1)

您需要先定义组。这需要一个排序,所以我假设你有一个名为import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListeningExecutorService; import com.google.common.util.concurrent.MoreExecutors; import java.util.ArrayList; import java.util.List; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; public class TestThread { public static List<Integer> execute(ExecutorService executorService, Callable<Integer> callable, int calls) throws ExecutionException, InterruptedException { ListeningExecutorService listeningExecutorService = MoreExecutors.listeningDecorator(executorService); List<ListenableFuture<Integer>> futures = new ArrayList<>(); for (int i = 0; i < calls; i++) { futures.add(listeningExecutorService.submit(callable)); } return Futures.allAsList(futures).get(); } } 的列,它指定了行的顺序。

然后可以将该组定义为id中0的累积总和:

c1

然后,基本上你想要的是select t1.*, sum(case when c1 = 0 then 1 else 0 end) over (order by id) as grp from table1 t1; 一些条件逻辑:

row_number()

您的问题不清楚select t1.*, (case when c1 = 0 then 0 else row_number() over (partition by grp order by id) end) as newcol from (select t1.*, sum(case when c1 = 0 then 1 else 0 end) over (order by id) as grp from table1 t1 ) t1; 的用途。您可能还需要按nr分区所有分析函数。

答案 1 :(得分:0)

with data (rn, nr, c1, desired_output) as
(
  select rownum, t.* from (select * from table1 /* order by some col */ ) t   
  -- http://searchoracle.techtarget.com/answer/What-is-Oracle-s-default-sorting-behavior 
  -- https://community.oracle.com/thread/3714691   
)
,
cte (rn, nr, c1, desired_output, do_2) as
(
  select rn, nr, c1, desired_output, case when c1 =0 then 0 else 1 end 
  from data where rn = 1
  union all
  select data.rn, data.nr, data.c1, data.desired_output, case when data.c1 = 0 then 0 else cte.do_2 + 1 end 
  from data join cte on (cte.rn + 1 = data.rn)
)
select * from cte;