Oracle sql计数值,直到特定列发生变化

问题描述:

我尝试为特定任务计数值,即使它们未被更改。 我需要统计每周的状态,直到状态改变(然后新的状态必须被计数)。 作为基本值的结果,我得到了下表。Oracle sql计数值,直到特定列发生变化

 
SRQNR  KW Status 
TB-17-0002 1 Status 05 
TB-17-0002 1 Status 20 
TB-17-0002 1 Status 25 
TB-17-0002 1 Status 30 
TB-17-0002 8 Status 40 
TB-17-0002 8 Status 44 
TB-17-0002 8 Status 45 
TB-17-0004 1 Status 05 
TB-17-0004 1 Status 20 
TB-17-0004 2 Status 25 
TB-17-0004 2 Status 30 
TB-17-0004 2 Status 40 
TB-17-0004 2 Status 44 
TB-17-0004 4 Status 70 
TB-17-0004 4 Status 85 
TB-17-0004 4 Status 90 
TB-17-0005 1 Status 05 
TB-17-0005 1 Status 20 
TB-17-0005 1 Status 25 
TB-17-0005 1 Status 30 
TB-17-0005 2 Status 40 
TB-17-0005 2 Status 44 
TB-17-0005 6 Status 45 
TB-17-0006 1 Status 05 
TB-17-0006 1 Status 20 
TB-17-0006 1 Status 25 
TB-17-0006 1 Status 30 
TB-17-0006 1 Status 40 
TB-17-0006 11 Status 44 
TB-17-0006 11 Status 45 
TB-17-0007 1 Status 05 
TB-17-0007 1 Status 20 
TB-17-0007 1 Status 25 
TB-17-0007 1 Status 30 
TB-17-0007 2 Status 40 
TB-17-0007 2 Status 44 
TB-17-0007 2 Status 45 
TB-17-0008 1 Status 05 
TB-17-0008 1 Status 20 
TB-17-0008 2 Status 25 
TB-17-0008 2 Status 30 
TB-17-0008 2 Status 40 
TB-17-0008 2 Status 44 
TB-17-0008 2 Status 45 
TB-17-0009 1 Status 05 
TB-17-0009 1 Status 20 
TB-17-0009 1 Status 25 
TB-17-0009 1 Status 30 
TB-17-0009 1 Status 40 
TB-17-0009 15 Status 44 
TB-17-0009 15 Status 45 
TB-17-0010 1 Status 05 
TB-17-0010 1 Status 20 
TB-17-0010 1 Status 25 
TB-17-0010 1 Status 30 
TB-17-0010 1 Status 40 
TB-17-0010 1 Status 44 
TB-17-0010 5 Status 45 
TB-17-0011 1 Status 05 
TB-17-0011 1 Status 20 
TB-17-0011 1 Status 25 
TB-17-0011 11 Status 30 
TB-17-0011 11 Status 40 
TB-17-0011 11 Status 44 
TB-17-0011 11 Status 70 
TB-17-0011 11 Status 85 
TB-17-0011 20 Status 90 

例如,srqnr TB-17-0002中KW8了状态30 KW 1和变为状态40。 现在我的愿望是KW 2,3,4,5,6,7状态30将被计数。

Interpretation

由于SRQNS仍处于KW 3或4状态30,这应是在解释为好。

感谢您的解决方案。

+0

什么是KWS的数量和它从何而来? – Serg

+1

您可以使用值填写您想要的输出吗?我希望你不需要全零,但不确定你期望的值。 – Degan

+0

我无法看到此问题的标题和请求的结果集格式之间的关联。 –

使用派生的一组范围作为行,KW作为一组列,这似乎希望按这些范围进行分组,然后按KW值进行旋转。从给出的这个结果产生的样本数据:

+----------+------+------+------+------+------+------+------+------+------+------+----+------+------+------+------+------+------+------+------+------+ 
| RANGES | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 
+----------+------+------+------+------+------+------+------+------+------+------+----+------+------+------+------+------+------+------+------+------+ 
| <=29  | 31 | 4 | null | null | null | null | null | null | null | null | 1 | null | null | null | null | null | null | null | null | null | 
| 30 to 69 | 4 | 10 | null | null | 1 | 1 | null | 3 | null | null | 4 | null | null | null | 2 | null | null | null | null | null | 
| 70 to 84 | null | null | null | 1 | null | null | null | null | null | null | 1 | null | null | null | null | null | null | null | null | null | 
| 85 to 90 | null | null | null | 2 | null | null | null | null | null | null | 1 | null | null | null | null | null | null | null | null | 1 | 
+----------+------+------+------+------+------+------+------+------+------+------+----+------+------+------+------+------+------+------+------+------+ 

使用此查询:

SELECT 
    * 
FROM (
     select 
      case when substr(status,-2,2) < '30' then '<=29' 
       when substr(status,-2,2) between '30' and '69' then '30 to 69' 
       when substr(status,-2,2) between '70' and '84' then '70 to 84' 
       when substr(status,-2,2) between '85' and '90' then '85 to 90' 
       else '???' 
       end as ranges 
     , KW 
     , count(*) as counter 
     from mytable t 
     group by 
      case when substr(status,-2,2) <= '30' then '<=29' 
       when substr(status,-2,2) between '30' and '69' then '30 to 69' 
       when substr(status,-2,2) between '70' and '84' then '70 to 84' 
       when substr(status,-2,2) between '85' and '90' then '85 to 90' 
       else '???' 
       end 
     , KW 
     ) 
PIVOT (
    SUM(counter) 
    FOR 
     (KW) 
    IN 
     (1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20) 
    ) 
; 

说明我还没有试过要小心的从子状态处理到的范围。您可能更愿意使用IN(...),具体取决于该列中的实际数据。

dbfiddle here