SQL查询以查找值的系列长度

时间:2016-07-04 18:26:32

标签: sql oracle oracle12c

我需要一个查询来评估FL_SUCC_EXEC列中后续“1”的最长不间断系列。对于表TEST(row_no number, fl_succ_exec number(1))中的以下数据,查询结果应为“6”。

行按row_no排序。

    ROW_NO   FL_SUCC_EXEC
---------- ------------
         1            1
         2            1
         3            1
         4            0
         5            1
         6            1
         7            1
         8            1
         9            1
        10            1
        11            0                               
        12            1
        13            1
        14            1  
        15            1  

我可以在PL / SQL中执行此操作:

declare
temp_cnt pls_integer default 0;
total_cnt pls_integer default 0;
begin
for rec in (select row_no, fl_succ_exec from test order by row_no)
loop
  if temp_cnt > total_cnt
   then 
   total_cnt:=temp_cnt;
  end if;

  if rec.fl_succ_exec!=0 
  then
     temp_cnt:=temp_cnt+rec.fl_succ_exec;
  else
     temp_cnt:=0;
  end if;

end loop;
dbms_output.put_line(total_cnt);
end;

但我仍然希望使用SQL解决方案。有没有?

2 个答案:

答案 0 :(得分:1)

Oracle安装程序

CREATE TABLE test ( row_no, fl_succ_exec ) AS
  SELECT  1, 1 FROM DUAL UNION ALL
  SELECT  2, 1 FROM DUAL UNION ALL
  SELECT  3, 1 FROM DUAL UNION ALL
  SELECT  4, 0 FROM DUAL UNION ALL
  SELECT  5, 1 FROM DUAL UNION ALL
  SELECT  6, 1 FROM DUAL UNION ALL
  SELECT  7, 1 FROM DUAL UNION ALL
  SELECT  8, 1 FROM DUAL UNION ALL
  SELECT  9, 1 FROM DUAL UNION ALL
  SELECT 10, 1 FROM DUAL UNION ALL
  SELECT 11, 0 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;

<强>查询

SELECT MAX( num_1s ) AS num_1s
FROM   (
  SELECT COALESCE(
           row_no - LAST_VALUE( CASE fl_succ_exec WHEN 0 THEN row_no END )
                      IGNORE NULLS OVER ( ORDER BY row_no ),
           ROWNUM
         ) AS num_1s
  FROM   test
);

<强>输出

NUM_1S
------
     6

答案 1 :(得分:1)

尝试:

SELECT max( count(*) ) As longest_uninterrupted_series
FROM (
    select fl_succ_exec,
           sum( case when fl_succ_exec = 1 then 0 else 1 end ) 
              over ( order by row_no ) xx 
    from test
)
WHERE fl_succ_exec = 1
GROUP BY xx;