简体   繁体   中英

oracle sql count value for weeks until a specific column changes

i try to count values for specific tasks even if they not have been changed. I need to count the status for every week, until the status changes (then the new status have to be count). I got the following table as a result for the basic values.

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

For example the srqnr TB-17-0002 got Status 30 in KW 1 and changes to Status 40 in KW8. Now my aspiration is that for KW 2,3,4,5,6,7 Status 30 will be counted.

解释

Because the SRQNS is still in KW 3 or 4 in Status 30 and this should be in the interpretation as well.

Thanks for your solutions.

With a derived set of ranges as rows, and KW as a set of columns, this appears to want grouping by those ranges, then pivoting by KW values. From the sample data given this result was produced:

+----------+------+------+------+------+------+------+------+------+------+------+----+------+------+------+------+------+------+------+------+------+
|  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    |
+----------+------+------+------+------+------+------+------+------+------+------+----+------+------+------+------+------+------+------+------+------+

Using this query:

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)
    )
;

Note I have not tried to be careful with the substring handling from Status to ranges. You might prefer to use IN(...) depending on the actual data in that column.

dbfiddle here

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM