스탭쿼리 . 너무 어려워요.고수님들 부탁드립니다 0 14 915

by 초보개발 [PL/SQL] [2017.07.20 22:53:33]


안녕하세요

쿼리를 작성중입니다. 도무지 감을 못잡아서.ㅠㅠ

데이타

번호 라인
1 T1 a
2 T1 b
3 T1 a
4 T1 a
5 T1 c
     

세번째 열이  변경되는 데에 관한 프로세서입니다.

값이 a=>b  바뀌는 값이니 정상.

        b=>a 돌아갈 때는 비정상(기존에 값으로 돌아갈때)

        a=>a 같은 값이니까 정상.

        a=>c 바뀌는 값이니 정상

라인 하나에 동적으로 값이 나오며 그값역시 정해져있지 않은 상태입니다.

예를 들면 행이  ababab  비정상 -a로 다시 되돌아가서 비정상

                         aaaaab 정상

                         aaabbc 정상

                         abcdef  정상

  그리고 마지막으로 T1라인에서 a로 돌아가는 회수를 구해야합니다.

가능할까요?  초보는 너무 어렵습니다.

통계함수역시 그전 행만 참조하는걸 봐서.

고수님들 제발부탁드립니다.

by 마농 [2017.07.21 08:06:50]

1. 정상 비정상을 어떻게 표현하나요?
 - 각 행별로 표시하나요?
 - 하나의 라인별로 집계하여 표시하나요?
2. a 로 돌아가는 회수라?
 - c > b 로 가는 경우도 비정상인데, a 로 갈때만 카운트 하나요?
 - 혹시 항상 a 로 돌아가나요? c > b 로 가는 경우는 없나요?
 - 라인별 첫행은 항상 a 에서 시작하나요?


by jkson [2017.07.21 08:09:24]
with  t
as (
select '1' as seq,'T1' as line,'a' as val from dual union all
select '2','T1','b' from dual union all
select '3','T1','a' from dual union all
select '4','T1','a' from dual union all
select '5','T1','c' from dual 
)
select line
     , listagg(val) within group(order by seq) vallist
     , decode(nvl(sum(fg),0),0,'정상','비정상') fg1
     , nvl(sum(fg),0) fg2
  from
    (
    select seq, line, val
         , case when val < lag(val) over (partition by line order by seq) then 1 end fg 
      from t
    )
 group by line

 


by 초보개발 [2017.07.21 09:19:03]

두분다 너무 감사드립니다.

보완사항이 조금 있어서 한번만 더 봐주세요. 너무 급한 마음에.

a>b>a>b>c

첫번째  정상

두번째 정상

세번째 비정상  :a로 돌아가서 

네번째 비정상  :b로 돌아가서 

다섯번째 정상 : a 나 b로 돌아가지 않고 

                          새로운 값이라서 

 

늘 a로 시작하는건 아니구요.

정상.비정상은 행단위로 나와야합니다.

부탁드립니다.


by jkson [2017.07.21 09:25:38]
with  t
as (
select '1' as seq,'T1' as line,'a' as val from dual union all
select '2','T1','b' from dual union all
select '3','T1','a' from dual union all
select '4','T1','b' from dual union all
select '5','T1','c' from dual 
)
select seq, line, val
     , case when val >= nvl(max(val) over(partition by line order by seq rows between unbounded preceding and 1 preceding),'!')
            then '정상'
            else '비정상'
       end fg 
  from t

'T1라인에서 a로 돌아가는 회수를 구해야합니다.' => 이건 어디에 표시되어야 하는 거죠?

그리고 실제 값이 'a', 'b' 이런 식으로 알파벳 증가 구조로 되어있는 건지도 궁금하네요.

결과값이 어떻게 나와야 된다 적어주시면 더 좋습니다.

추가)

오잉.. 생각해보니 네번째 비정상은요.. 기존에 b가 max 값이 였는데 왜 비정상이죠?

a->a->a의 경우에는 기존에 값이 나와도 정상인데요.


by 마농 [2017.07.21 09:38:25]

음. 동일한 값이 나오는 것은 정상이라고 하셨던거 같은데?
a a b b c 는 정상이겠죠?
a b a b c 에서
세번째 a 는 비정상인데(b 로 갔다가 다시 a로 왔으므로)
네번째 b 는 정상으로 볼 수도 있는 것 아닌가요? (이전 최대값인 b 가 다시 나왔으므로. 아직 c로 안간 상태)


by 초보개발 [2017.07.21 09:54:16]

감사합니다.

결과값을  보여드릴께요.

새로운값은 늘 정상이고 

기존값들을 검색해서 있고

그전 로우와 비교해서 다르면 비정상입니다.

임시테이블을 사용해볼까요? 되는지요?

라인 플러그
T1 a 정상
T1 b 정상
T1 a 비정상
T1 b 비정상
T1 c 정상

 


by 마농 [2017.07.21 09:59:38]

a b a b b c 처럼 5번째에 b 가 추가된다면?
5번째에 b 는 정상인가요?
a b a a a a 에서 3번째 a 만 비정상이고 네번째 이후 a 는 모두 정상인가요?


by 초보개발 [2017.07.21 10:07:17]

네.마농님.

다섯번째 b는 이전행과 동일해서 정상이구요.

네번째 a추가도 정상입니다.

감사합니다.


by 마농 [2017.07.21 10:35:54]

a 로 돌아가는 회수 관련 입장도 밝혀 주세요.
 - a 로 돌아가는 것만 의미하는지? b로 돌아가는 것은?
 - 혹, 비정상 횟수를 의미하는 것은 아닌지?
 - 위의 행별 flag 표현과 별개의 쿼리를 원하는 건지?
 - 함께 보여주길 원하는 건지? 그렇다면 표현 방법은?
 

SELECT seq, line, val
     , CASE WHEN MAX(val) OVER(PARTITION BY line ORDER BY seq
                 ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING) >= val
             AND LAG(val) OVER(PARTITION BY line ORDER BY seq) != val
            THEN '비정상' ELSE '정상' END flag
  FROM t
;

 


by 초보개발 [2017.07.21 12:50:33]

정말 감사합니다.마농님.

근본적으로 라인별 정상,비정상 카운터 하는 프로세서입니다.

a나 b로 돌아가는 회수는 별상관이 없습니다.

보내주신 쿼리 중 

case 문에 max를 값을 사용하셨는데  

죄송한데요.

case문을 마지막으로 설명부탁드려도 될까요? 잘 이해가 안되서요

너무 고맙습니다.


by 초보개발 [2017.07.21 13:54:52]

죄송합니다.마농님.

테스트를 하다보니 a로 시작해서 오름차순은 괜찮은데  

b   a  b  a  b  이런식으로 

만약 b로 시작해서 a로 진행되면  

두번째 a에서 비정상이 나오네요.

혹 max값 때문에 그런가요?


by 마농 [2017.07.21 14:30:05]

b 가 a 보다 크므로 비정상 아닌가요?


by jkson [2017.07.21 14:14:25]

코드가 증가하는 구조가 아닌 것 같아

알파벳으로 증가하는 구조가 맞냐고 질문드렸었는데..;;

마농님 답변 수정해서

SELECT seq, line, val
     , CASE WHEN row_number() OVER(PARTITION BY line, val ORDER BY seq) != 1
             AND LAG(val) OVER(PARTITION BY line ORDER BY seq) != val
            THEN '비정상' ELSE '정상' END flag
  FROM t
;

이렇게 하시면 될 것 같고

의미는 현재 val이 처음 나온 값이 아니고(row_number부분) 직전 값과 다르면(lag부분) 비정상 그게 아니면 정상


by 초보개발 [2017.07.21 22:12:03]

두분 너무 고맙습니다.

쿼리는 모르겠고 일정은 팍팍한 데

프로세서도 정확하지 않은데다

경우의 수도 많아서 물어볼곳도 없어

답답했거든요.

일단 마지막 보내주신 jkson님의 쿼리로 

작업을 했습니다. a b의 max값보다 순서가 중요한 테이블을 검색하는 거였습니다.

이번 계기로 정말 쿼리공부를 많이 해야겠습니다.여기사이트를 꾸준히 봐도 되겠디요? 

감사드립니다.

댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입