按序列号分组的问题

时间:2012-07-26 00:34:11

标签: oracle plsql oracle11g

我基本上是在执行以下操作的sql之后。我关注的是B列更改时的一系列连续数字,但是依次保留列ID 我已经尝试过密集等级,但它总是抛出ID列的序列,这会混淆我所追求的内容。有什么想法吗?

ID||A||B
01||T||1
02||T||1
03||T||0
04||T||0
05||T||1
06||T||1
07||T||1
08||T||0
09||T||1
10||T||1
11||T||0

INTO

ID||A||B||C
01||T||1||1
02||T||1||1
03||T||0||2
04||T||0||3
05||T||1||4
06||T||1||4
07||T||1||4
08||T||0||5
09||T||1||6
10||T||1||6
11||T||0||7

1 个答案:

答案 0 :(得分:2)

--#3: Running total of value changes
select id, a, b
    ,sum(has_changed) over (partition by A order by id
        rows between unbounded preceding and current row) c
from
(
    --#2: Find rows where the value changed.
    select id, a, b
        ,case
            when b = lag(b) over (partition by A order by id) then 0
            else 1
        end has_changed    
    from
    (
        --#1: Test data
        select '01' ID, 'T' A, 1 B from dual union all
        select '02' ID, 'T' A, 1 B from dual union all
        select '03' ID, 'T' A, 0 B from dual union all
        select '04' ID, 'T' A, 0 B from dual union all
        select '05' ID, 'T' A, 1 B from dual union all
        select '06' ID, 'T' A, 1 B from dual union all
        select '07' ID, 'T' A, 1 B from dual union all
        select '08' ID, 'T' A, 0 B from dual union all
        select '09' ID, 'T' A, 1 B from dual union all
        select '10' ID, 'T' A, 1 B from dual union all
        select '11' ID, 'T' A, 0 B from dual
    ) test_data
)
order by id;

结果:

ID  A   B   C
01  T   1   1
02  T   1   1
03  T   0   2
04  T   0   2
05  T   1   3
06  T   1   3
07  T   1   3
08  T   0   4
09  T   1   5
10  T   1   5
11  T   0   6

不完全一样,虽然我认为你的例子有一个额外的增量,正如@Adam Hawkes指出的那样。


<强>更新

这将产生您的预期结果:

--#3: Running total of value changes, or where the value is 0
select id, a, b
    ,sum(has_changed_or_0) over (partition by A order by id
        rows between unbounded preceding and current row) c
from
(
    --#2: Find rows where the value changed, or where value is 0
    select id, a, b
        ,case
            when b = 0 then 1
            when b = lag(b) over (partition by A order by id) then 0
            else 1
        end has_changed_or_0
    from
    (
        --#1: Test data
        select '01' ID, 'T' A, 1 B from dual union all
        select '02' ID, 'T' A, 1 B from dual union all
        select '03' ID, 'T' A, 0 B from dual union all
        select '04' ID, 'T' A, 0 B from dual union all
        select '05' ID, 'T' A, 1 B from dual union all
        select '06' ID, 'T' A, 1 B from dual union all
        select '07' ID, 'T' A, 1 B from dual union all
        select '08' ID, 'T' A, 0 B from dual union all
        select '09' ID, 'T' A, 1 B from dual union all
        select '10' ID, 'T' A, 1 B from dual union all
        select '11' ID, 'T' A, 0 B from dual
    ) test_data
)
order by id;