1

我有一个这样的数据集

Name      Service       Continuous      Start          End
A              4                 Y      04/06/2013     31/12/9999 
A              2                 N      02/02/2013     04/02/2013
B              3                 Y      05/06/2013     31/12/9999
B              2                 Y      02/06/2013     04/06/2013
B              5                 Y      27/05/2013     01/06/2013
B              4                 N      13/04/2013     17/04/2013
B              3                 Y      09/04/2013     12/04/2013
B              1                 Y      07/04/2013     08/04/2013

我需要为每个人添加第一组连续服务期。对之前的连续服务周期并不真正感兴趣,因为设置了标志只查找之前的一个周期。所以输出将是这样的:

Name        Current continuous service
A               4
B               10

请为 B 而不是 14。任何人都可以帮助我使用 plsql 吗?

4

2 回答 2

2

不需要 PL/SQL 过程。

窗口(又名“分析”)函数可用于检测连续标志的变化:

select name, sum(service)
from (
    select *,
           case
              when lag(continuous,1,continuous) over (partition by name order by start_date desc) = continuous then 1
              else null
            end as is_valid
    from data_set
) t
where is_valid = 1
group by name;

SQLFiddle 示例:http ://sqlfiddle.com/#!4/f846b/2

编辑:我注意到这不会只获得“第一”组连续值。要正确考虑该限制,需要稍微复杂一点的查询:

select name, sum(service)
from (
    select *,
           case
              when continuous = 'Y' or lag(continuous) over (partition by name order by start_date desc) is null then 1
              when lag(continuous,1,continuous) over (partition by name order by start_date desc) = continuous then 0
              else null
            end as marker,
            row_number() over (partition by name order by start_date desc) as rn,
            count(case when continuous = 'Y' then 1 else null end) over (partition by name order by start_date desc) as cont_count
    from data_set
) t1
where rn = cont_count 
  and marker = 1
group by name
order by name;

SQLFiddle 用于第二个解决方案(包括“B”的“第二个”连续组):
http ://sqlfiddle.com/#!4/0ca46/2

于 2013-06-08T09:27:00.387 回答
0

假设集合如下:

 SL_NO VAL_1      VAL_2 VAL_3
     1 A              4 Y     
     2 A              2 N     
     3 B              3 Y     
     4 B              2 Y     
     5 B              5 Y     
     6 B              4 N     
     7 B              3 Y     


SET serveroutput ON
DECLARE
     total NUMBER := 0;
BEGIN
     FOR rec IN
     (SELECT DISTINCT val_1 FROM my_test
     )
     LOOP
          FOR rec2 IN
          (SELECT val_1, val_2, val_3
          FROM mY_test
          WHERE val_1 = rec.val_1
          ORDER BY sl_no
          )
          LOOP
               IF rec2.val_3 = 'Y' THEN
                    total   := total + rec2.val_2;
               ELSE
                    dbms_output.put_line(rec2.val_1||' '||' '||total);
               END IF;
          END LOOP;
          total := 0;
     END LOOP;
END;
于 2013-06-07T04:25:02.520 回答