연속되는 것과 안되는것을 뽑고 싶어요 ㅠ 1 7 1,383

by 혜당화 [SQL Query] 연속 비연속 [2015.08.04 10:41:30]


A =마스터 테이블

SEQ 가 존재

 

B = 포장 테이블

A.SEQ  포장_넘버

A.SEQ 포장넘버
1 1
1 2
1 3
1 4
1 5
1 6
1 7
1 8
1 9
1 10
1 B
1 C
1 D

과 같이 형태가 있습니다.

포장번호는 16진수 이며 

고객이 원하는 형태는

SEQ 포장
1 1~10,B~D
2 1~3,7,10

 

와 같이 연속된 값이면 ~로 가고 중간중간에 하나만 있는숫자는 콤마로 구분해주길 원합니다.

하나의 쿼리로 짜볼려니 머리가 안굴러가네요 ㅠㅠ 고수님들의 조언을 부탁드립니다.

 

by DarkBee [2015.08.04 11:00:42]

10은 16진수 표현으로 A 아닌가요???


by 혜당화 [2015.08.04 11:06:07]

급하게 적느라 생각을 못했네요 ㅠㅠ


by jkson [2015.08.04 11:36:33]
with t as
(
select 1 seq, '1' num from dual
union all
select 1 seq, '2' num from dual
union all
select 1 seq, '3' num from dual
union all
select 1 seq, '4' num from dual
union all
select 1 seq, '5' num from dual
union all
select 1 seq, '6' num from dual
union all
select 1 seq, '7' num from dual
union all
select 1 seq, '8' num from dual
union all
select 2 seq, '9' num from dual
union all
select 2 seq, 'A' num from dual
union all
select 1 seq, 'B' num from dual
union all
select 1 seq, 'C' num from dual
union all
select 1 seq, 'D' num from dual
)
select seq,listagg(num,',') within group(order by to_number(regexp_substr(num,'[^~]+',1,1),'XX')) numlist
  from
    (
    select  seq, decode(min(num),max(num),min(num),min(num)||'~'||max(num)) num
      from
        (
        select seq
            ,  num
            ,  to_number(num,'XX') numtran
            ,  row_number() over(partition by seq order by  to_number(num,'XX')) rn 
          from t
        )
      group by seq, numtran - rn
    )
 group by seq

제가 잘 이해한 건지 모르겠네요 seq별로 연속인 것들끼리 묶어서 표현하는 거 맞나요?


by 창조의날개 [2015.08.04 13:30:14]

WITH A AS (
    SELECT 1 SEQ, '1' PNO FROM DUAL
    UNION ALL SELECT 1 SEQ, '2' PNO FROM DUAL
    UNION ALL SELECT 1 SEQ, '3' PNO FROM DUAL
    UNION ALL SELECT 1 SEQ, '4' PNO FROM DUAL
    UNION ALL SELECT 1 SEQ, '5' PNO FROM DUAL
    UNION ALL SELECT 1 SEQ, '6' PNO FROM DUAL
    UNION ALL SELECT 1 SEQ, '8' PNO FROM DUAL
    UNION ALL SELECT 1 SEQ, '9' PNO FROM DUAL
    UNION ALL SELECT 1 SEQ, 'A' PNO FROM DUAL
    UNION ALL SELECT 1 SEQ, 'B' PNO FROM DUAL
    UNION ALL SELECT 2 SEQ, '1' PNO FROM DUAL
    UNION ALL SELECT 2 SEQ, '2' PNO FROM DUAL
    UNION ALL SELECT 2 SEQ, '3' PNO FROM DUAL
    UNION ALL SELECT 2 SEQ, '7' PNO FROM DUAL
    UNION ALL SELECT 2 SEQ, '9' PNO FROM DUAL
    UNION ALL SELECT 2 SEQ, 'C' PNO FROM DUAL
    UNION ALL SELECT 2 SEQ, 'D' PNO FROM DUAL
    UNION ALL SELECT 2 SEQ, 'E' PNO FROM DUAL
    UNION ALL SELECT 2 SEQ, 'F' PNO FROM DUAL
)
SELECT SEQ, ListAgg(NO, ',') WITHIN GROUP(ORDER BY SEQ) 포장
FROM (
      SELECT SEQ
           , MIN(PNO)||DECODE(MIN(PNO),MAX(PNO),NULL,'~'||MAX(PNO)) NO
      FROM (
            SELECT SEQ, PNO
                 , TO_NUMBER(PNO,'XX')
                   - ROW_NUMBER () OVER (PARTITION BY SEQ ORDER BY PNO) AS GP
            FROM A
      )
      GROUP BY SEQ, GP
)
GROUP BY SEQ
;

 


by 마농 [2015.08.04 14:10:07]

Order By seq 를 하면 정확한 정렬이 보장되지 않을 수 있습니다.

MIN(pno)도 마찬가지입니다. pno 가 문자이므로 정확한 값이 아닙니다.


by 창조의날개 [2015.08.04 14:26:09]

그렇겠네요..

16진수라는 생각만 했지 예문이 한자리라 자리수가 늘어날 거라는 생각을 못했네요..


by 마농 [2015.08.04 14:12:48]
SELECT seq
     , LISTAGG(x, ',') WITHIN GROUP(ORDER BY s)
  FROM (SELECT seq
             , MIN(x) s
             , TO_CHAR(MIN(x), 'fmXX') ||
               DECODE(COUNT(*), 1, '', '~'||TO_CHAR(MAX(x), 'fmXX')) x
          FROM (SELECT seq, num
                     , TO_NUMBER(num, 'xx') x
                     , ROW_NUMBER() OVER(
                       PARTITION BY seq ORDER BY TO_NUMBER(num, 'xx')) rn
                  FROM t
                )
         GROUP BY seq, x - rn
        )
 GROUP BY seq
 ORDER BY seq
;

 

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