Master -Detail 구조를 한줄 묶음으로... 0 6 6,735

by 나그네 [SQL Query] Lag Lead [2014.06.29 12:13:35]


안녕하세요...고민하다가 의견을 구해 봅니다.

 

A table   B table
           
key header T/F   key detail
1 aaa TRUE   2
2 bbb FALSE   2
3 ccc FALSE   2
4 ddd TRUE   3
        3
        3
        3
        3
        3
           

 위의 두 데이블은 key로 header(A 테이블) ,detail(B 테이블) 구조를 이룹니다.

A 테이블에 T/F칼럼의 값이 FALSE 일때만 B 테이블의 데이타가 들어갑니다.(TRUE 일때는 데이타 없음)

 아래의 데이타 추출 방법이 A 테이블의 T/F 칼럼의 값에 따라 detail 과 관계를 고려해서,

T/F 칼럼 값이 TRUE이면 Key에 대하여 한줄만 header 칼럼값만 뿌려주고,

T/F칼럼 값이 TRUE 처럼 한 ROW를 뿌려 주고,

FALSE에 관련된 detail 항목 값을 한 Row에 묶어서 보여주는것입니다.

그런데 False일때 Detail항목이 3개 이하면 그대로 보여주지만 3개 이상이 되면 3개를 묶어서 보여주고 .

ccc[가,나,다 외] 식으로 보여주는것입니다.

아래 추출 데이타 식으로 나타낼수 있을까요?

추출 데이터
no key Header Name 분류
1 1 aaa TRUE
2 2 bbb TRUE
3 2 bbb[가,나,다] FALSE
4 3 ccc TRUE
5 3 ccc[가,나,다 외] FALSE
6 4 ddd TRUE

select  ---


from (          select 1 as key , 'aaa' as header , 'TRUE'  as "T/F" from dual
      union all select 2 as key , 'bbb' as header , 'FALSE' as "T/F" from dual
      union all select 3 as key , 'ccc' as header , 'FALSE' as "T/F" from dual
      union all select 4 as key , 'ddd' as header , 'TRUE'  as "T/F" from dual) A,
     (          select 2 as key , '가' as detail from dual
      union all select 2 as key , '나' as detail from dual
      union all select 2 as key , '가' as detail from dual
      union all select 2 as key , '나' as detail from dual
      union all select 2 as key , '다' as detail from dual
      union all select 2 as key , '라' as detail from dual
      union all select 2 as key , '마' as detail from dual) B

고수들의 조언을 바랍니다...즐거운 하루 되세용^^

by 시골간아찌 [2014.06.29 14:12:19]

B테이블에 KEY가 전부 2네요


by 나그네 [2014.06.29 16:31:02]

B 테이블은 Detail 테이블로 A테이블 key인 2와 3이 있습니

A테이블은 마스트로 A테이블 해당 하는 Key가 B테이블에 반드시 있는것은 아닙니다.


by 시골간아찌 [2014.06.29 14:23:34]

여긴 오라클이 안되서.. 대충 쓰면

SELECT KEY , HEADER_NAME , 1 SEQ  FROM A

UNION ALL

SELECT

KEY ,

'['|| (SELECT HEADER_NAME FROM A WHERE A.KEY = B1.KEY) ||WN_CONCAT(DETAIL) || CASE WHEN MAX(CNT)>3 THEN ' 외' ) || ']'  HEADER _NAME ,

2 SEQ

FROM

(SELECT KEY , DETAIL

        ,  ROW_NUMBER() OVER(PARTITION BY KEY ORDER BY DETAIL) RN  

        , COUNT(*) OVER(PARTITION BY KEY ) CNT FROM B ) B1

WHERE RN <= 3

GROUP BY KEY

ORDER BY KEY , SEQ

 


by 마농 [2014.06.30 10:10:25]
WITH a AS
(
SELECT 1 key, 'aaa' header, 'TRUE' "T/F" FROM dual
UNION ALL SELECT 2, 'bbb', 'FALSE' FROM dual
UNION ALL SELECT 3, 'ccc', 'FALSE' FROM dual
UNION ALL SELECT 4, 'ddd', 'TRUE'  FROM dual
)
, b AS
(
SELECT 2 key, '가' detail FROM dual
UNION ALL SELECT 2, '나' FROM dual
UNION ALL SELECT 2, '다' FROM dual
UNION ALL SELECT 3, '가' FROM dual
UNION ALL SELECT 3, '나' FROM dual
UNION ALL SELECT 3, '다' FROM dual
UNION ALL SELECT 3, '라' FROM dual
UNION ALL SELECT 3, '마' FROM dual
UNION ALL SELECT 3, '바' FROM dual
)
SELECT ROW_NUMBER() OVER(ORDER BY a.key, a."T/F" DESC) no
     , a.key
     , a.header||b.x header_name
     , a."T/F"
  FROM (SELECT key, header
             , DECODE(lv, 2, 'TRUE', "T/F") "T/F"
          FROM a
             , (SELECT LEVEL lv FROM dual CONNECT BY LEVEL <= 2)
         WHERE lv <= DECODE("T/F", 'TRUE', 1, 2)
        ) a
     , (SELECT key
             , 'FALSE' "T/F"
             , '['||REGEXP_REPLACE(
               LISTAGG(detail, ',') WITHIN GROUP(ORDER BY detail)
               , '([^,]+,[^,]+,[^,]+),(.+)', '\1 외')||']' x
          FROM b
         GROUP BY key
        ) b
 WHERE a.key   = b.key  (+)
   AND a."T/F" = b."T/F"(+)
;

 


by 나그네 [2014.07.03 16:25:13]

마농님..감사합니다.

그럼 만약에 이런것도 될까요..

5 3 ccc[가,나,다 외] FALSE

를 3개 이상이면 가장 적은 순위인 가 와 바 를 표시 할수 있을까요..

즉 아래 와 같은 최소 값과 최대 값만을 표기 할수 있을까요..

5 3 ccc[가 ~ 바] FALSE

by 마농 [2014.07.03 17:01:24]
-------------- 변경전 -------------------------------------------------
--           , '['||REGEXP_REPLACE(
--             LISTAGG(detail, ',') WITHIN GROUP(ORDER BY detail)
--             , '([^,]+,[^,]+,[^,]+),(.+)', '\1 외')||']' x
-------------- 변경후1 ------------------------------------------------
             , '['||REGEXP_REPLACE(
               LISTAGG(detail, ',') WITHIN GROUP(ORDER BY detail)
               , '([^,]+)(,[^,]+){2,},([^,]+)', '\1 ~ \3')||']' x
-------------- 변경후2 ------------------------------------------------
             , '['||
                CASE WHEN COUNT(*) <= 3
                THEN LISTAGG(detail, ',') WITHIN GROUP(ORDER BY detail)
                ELSE MIN(detail) ||' ~ '||MAX(detail)
                 END||']' x
-- x 를 가져오는 부분만 수정하시면 되겠습니다. ------------------------

 

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