WITH MASTER_TABLE AS ( SELECT 1 AS GRP_SEQ, 'AG0000001' AS GRP_ID FROM DUAL ), DETAIL_TABLE AS ( SELECT 1 AS DETAIL_SEQ, 1 AS GRP_SEQ, '카테고리 > 전자기기' AS GRP_PATH, 'I' AS GRP_GUBUN FROM DUAL UNION ALL SELECT 2 AS DETAIL_SEQ, 1 AS GRP_SEQ, '카테고리 > 전자기기 > 컴퓨터' AS GRP_PATH, 'E' AS GRP_GUBUN FROM DUAL UNION ALL SELECT 3 AS DETAIL_SEQ, 1 AS GRP_SEQ, '카테고리 > 전자기기 > 노트북' AS GRP_PATH, 'I' AS GRP_GUBUN FROM DUAL UNION ALL SELECT 4 AS DETAIL_SEQ, 1 AS GRP_SEQ, '카테고리 > 전자기기 > 외장하드' AS GRP_PATH, 'I' AS GRP_GUBUN FROM DUAL ) SELECT A.GRP_SEQ, A.GRP_ID, B.GRP_PATH, B.GRP_GUBUN FROM MASTER_TABLE A INNER JOIN DETAIL_TABLE B ON A.GRP_SEQ = B.GRP_SEQ ;
안녕하세요.
제목을 한참 고민했는데요.
우선 데이터는 위와 같습니다.
총 4row 인데 GRP_GUBUN 값이 I인 경우, E인 경우 2가지가 존재합니다.
해당 데이터로 아래와 같은 결과값을 내고 싶습니다.
다만 GRP_GUBUN이 I인 값과 E인 값 어느쪽이 더 row가 많을 지는 알 수 없습니다. (데이터에 따라 달라집니다.)
현재 위에 적은 테스트 데이터 상에는 I인 값이 3건으로 더 많지만 실제 데이터는 I가 많을 수도 있고 E가 많을 수도 있고 같을 수도 있습니다.
-------------------------------------------------------------------------- GRP_SEQ GRP_ID GRP_PATH_I GRP_PATH_E -------------------------------------------------------------------------- 1 AG0000001 카테고리 > 전자기기 카테고리 > 전자기기 > 컴퓨터 -------------------------------------------------------------------------- 1 AG0000001 카테고리 > 전자기기 > 노트북 NULL -------------------------------------------------------------------------- 1 AG0000001 카테고리 > 전자기기 > 외장하드 NULL --------------------------------------------------------------------------
GRP_GUBUN이 I인 항목이 3row, E인 항목이 1row 인데
셀프조인 시 row를 3개로 출력까지 했으나 E인 항목이 1 row만 출력되는 것이 아니라 동일한 내용으로 3row가 출력됩니다.
1row만 출력되고 나머지 항목이 null로 뜨게끔 할 수 없을까요?
셀프 조인이 아닌 다른 방법으로 원하는 모양으로 결과값을 가져올 수 있는 방법이 있다면 조언 부탁 드립니다.
WITH detail_table AS ( SELECT 1 detail_seq, 1 grp_seq, 'AG0000001' grp_id, '카테고리 > 전자기기' grp_path, 'I' grp_gubun FROM dual UNION ALL SELECT 2, 1, 'AG0000001', '카테고리 > 전자기기 > 컴퓨터' , 'E' FROM dual UNION ALL SELECT 3, 1, 'AG0000001', '카테고리 > 전자기기 > 노트북' , 'I' FROM dual UNION ALL SELECT 4, 1, 'AG0000001', '카테고리 > 전자기기 > 외장하드', 'I' FROM dual ) -- 1. Group By, Min(Decode) SELECT grp_seq , grp_id , rn , MIN(DECODE(grp_gubun, 'I', grp_path)) grp_path_I , MIN(DECODE(grp_gubun, 'E', grp_path)) grp_path_E FROM (SELECT grp_seq, grp_id, grp_gubun, grp_path , ROW_NUMBER() OVER(PARTITION BY grp_seq, grp_id, grp_gubun ORDER BY detail_seq) rn FROM detail_table ) GROUP BY grp_seq, grp_id, rn ORDER BY grp_seq, grp_id, rn ; -- 2. PIVOT SELECT * FROM (SELECT grp_seq, grp_id, grp_gubun, grp_path , ROW_NUMBER() OVER(PARTITION BY grp_seq, grp_id, grp_gubun ORDER BY detail_seq) rn FROM detail_table ) PIVOT (MIN(grp_path) grp_path FOR grp_gubun IN ('I' i, 'E' e)) ORDER BY grp_seq, grp_id, rn ;
WITH MASTER_TABLE AS ( SELECT 1 AS GRP_SEQ, 'AG0000001' AS GRP_ID FROM DUAL ), DETAIL_TABLE AS ( SELECT 1 AS DETAIL_SEQ, 1 AS GRP_SEQ, '카테고리 > 전자기기' AS GRP_PATH, 'I' AS GRP_GUBUN FROM DUAL UNION ALL SELECT 2 AS DETAIL_SEQ, 1 AS GRP_SEQ, '카테고리 > 전자기기 > 컴퓨터' AS GRP_PATH, 'E' AS GRP_GUBUN FROM DUAL UNION ALL SELECT 3 AS DETAIL_SEQ, 1 AS GRP_SEQ, '카테고리 > 전자기기 > 노트북' AS GRP_PATH, 'I' AS GRP_GUBUN FROM DUAL UNION ALL SELECT 4 AS DETAIL_SEQ, 1 AS GRP_SEQ, '카테고리 > 전자기기 > 외장하드' AS GRP_PATH, 'I' AS GRP_GUBUN FROM DUAL ) SELECT CASE WHEN A.GRP_SEQ IS NULL THEN B.GRP_SEQ ELSE A.GRP_SEQ END AS GRP_SEQ, CASE WHEN A.GRP_ID IS NULL THEN B.GRP_ID ELSE A.GRP_ID END AS GRP_ID, A.INCLUDE_NM, B.EXCLUDE_NM FROM ( SELECT MT.GRP_SEQ, MT.GRP_ID, DT.GRP_GUBUN, DECODE(DT.GRP_GUBUN, 'I', DT.GRP_PATH) AS INCLUDE_NM, DECODE(DT.GRP_GUBUN, 'E', DT.GRP_PATH) AS EXCLUDE_NM, ROW_NUMBER() OVER (ORDER BY DT.DETAIL_SEQ DESC) AS ROW_NUM FROM DETAIL_TABLE DT INNER JOIN MASTER_TABLE MT ON DT.GRP_SEQ = MT.GRP_SEQ WHERE DT.GRP_GUBUN = 'I' ) A FULL OUTER JOIN ( SELECT MT.GRP_SEQ, MT.GRP_ID, DT.GRP_GUBUN, DECODE(DT.GRP_GUBUN, 'I', DT.GRP_PATH) AS INCLUDE_NM, DECODE(DT.GRP_GUBUN, 'E', DT.GRP_PATH) AS EXCLUDE_NM, ROW_NUMBER() OVER (ORDER BY DT.DETAIL_SEQ DESC) AS ROW_NUM FROM DETAIL_TABLE DT INNER JOIN MASTER_TABLE MT ON DT.GRP_SEQ = MT.GRP_SEQ WHERE DT.GRP_GUBUN = 'E' ) B ON A.GRP_SEQ = B.GRP_SEQ AND A.ROW_NUM = B.ROW_NUM ;
자문 자답이지만 하다보니 이렇게 해도 답이 나오네요!