2012-07-26 2 views
2

기본적으로 다음을 수행하는 sql 이후입니다. 나는 컬럼 B가 변할 때 순서대로 컬럼 ID를 유지하는 일련의 일련 번호 뒤에있다. 밀도가 높은 순위를 시도했지만 항상 내가 뒤죽박죽 인 ID 컬럼의 시퀀스를 버린다. 어떤 아이디어?시퀀스 번호 별 그룹 문제 Q

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

, ID와 행 = 4 열 C.의 증분 값은 정확한 것이되어왔다 ? –

답변

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 

하지 같은, 내가 @ 아담 호크스가 지적한대로 예, 여분의 증가가 있다고 생각하지만.


UPDATE 이것은 예상되는 결과를 생성

: 예상 출력

--#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; 
+0

많은 도움을 주신 데 대해 감사드립니다. 맞습니다. 증가 이유는 주어진 예에 따라 0이있는 항목이 증가해야한다는 것입니다. 이 이유는 B 열에서 1로 플래그가 지정된 것은 행이 서로 연속적이라는 것을 정의하기 때문입니다. 그러나 행이 0으로 돌아 오면 내 표류를 잡으면 시퀀스로 돌아와야합니다. 따라서 1,1,1,000011000이 B 열에 있으면 1,1,1,2,3,4,5,6과 같은 것을 읽을 것입니다. , 6,7,8,9 C 열에 있지만 ID 열의 순서는 오름차순으로 표시됩니다. jonearles는 거의 그것을 얻었다! – phatz