일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
Tags
- Excel
- 마이플랫폼
- 회계
- 톰캣
- DB
- oracle
- 성능
- 한글
- 데이터베이스
- Report Designer
- 도서
- JEUS
- Book
- 오라클
- java
- error
- 태그를 입력해 주세요.
- 기타소득
- 엑셀
- 함수
- 자바
- JavaScript
- 이클립스
- 튜닝
- Eclipse
- MIP
- miplatform
- 에러
- Tomcat
- 오류
Archives
- Today
- Total
어느 가을날의 전환점
ORACLE|오라클 레코드 한 문자열로 만들기(XMLAGG, LISTAGG 사용) 본문
출처 : http://raltigue.tistory.com/m/11
LISTAGG 함수가 도입되기 전에 동일 기능을 구현하기 위해 다양한 기법들이 사용되었다. 정리해보자.
아래와 같이 데이터를 생성하자.
CREATE TABLE t1 (c1 NUMBER(1), c2 VARCHAR2(2)); INSERT INTO t1 VALUES (1, '01'); INSERT INTO t1 VALUES (2, '02'); INSERT INTO t1 VALUES (2, '03'); INSERT INTO t1 VALUES (3, '04'); INSERT INTO t1 VALUES (3, '04'); INSERT INTO t1 VALUES (3, '05'); INSERT INTO t1 VALUES (3, '06');
① 11g를 사용한다면 LISTAGG 함수를 사용하면 된다. 집계함수(1번)와 분석함수(2번) 형태로 사용이 가능하다.
-- 1 SELECT a.c1, LISTAGG (a.c2, ',') WITHIN GROUP (ORDER BY a.c2) AS c2 FROM t1 a GROUP BY a.c1; C1 C2 --- ------------ 1 01 2 02,03 3 04,04,05,06 3 rows selected. -- 2 SELECT a.c1, LISTAGG (a.c2, ',') WITHIN GROUP (ORDER BY a.c2) OVER (PARTITION BY A.c1) AS c2 FROM t1 a; C1 C2 --- ------------ 1 01 2 02,03 2 02,03 3 04,04,05,06 3 04,04,05,06 3 04,04,05,06 3 04,04,05,06 7 rows selected.
② WM_CONCAT 함수는 WMSYS 유저가 내부적으로 사용한다. (SQL Reference에 없다...--;) LISTAGG보다 성능은 떨어지지만 추가 기능(DISTINCT 구문, 분석함수 누적, KEEP 절)을 지원한다. 4번 방식을 이용하면 정렬도 가능하다.
-- 1 SELECT a.c1, wmsys.wm_concat (a.c2) AS c2 FROM t1 a GROUP BY a.c1; C1 C2 --- ------------ 1 01 2 02,03 3 04,06,05,04 3 rows selected. -- 2 SELECT a.c1, wmsys.wm_concat (DISTINCT a.c2) AS c2 FROM t1 a GROUP BY a.c1; C1 C2 --- ------------ 1 01 2 02,03 3 04,05,06 3 rows selected. -- 3 SELECT a.c1, wmsys.wm_concat (a.c2) OVER (ORDER BY a.c2) AS c2 FROM t1 a; C1 C2 --- ---------------------- 1 01 2 01,02 2 01,02,03 3 01,02,03,04,04 3 01,02,03,04,04 3 01,02,03,04,04,05 3 01,02,03,04,04,05,06 7 rows selected. -- 4 SELECT a.c1, MAX (CAST (a.c2 AS VARCHAR2 (4000))) as c2 FROM (SELECT a.c1, wmsys.wm_concat (a.c2) OVER (PARTITION BY a.c1 ORDER BY a.c2) AS c2 FROM t1 a) a GROUP BY a.c1; C1 C2 --- ------------ 1 01 2 02,03 3 04,04,05,06 3 rows selected. -- 5 SELECT a.c1, wmsys.wm_concat (a.c2) KEEP (DENSE_RANK FIRST ORDER BY a.c2) AS c2 FROM t1 a GROUP BY a.c1; C1 C2 --- ------------ 1 01 2 02 3 04,04 3 rows selected.
③ 10g에서는 XMLAGG 함수를 사용해도 된다.
SELECT a.c1, SUBSTR (XMLAGG (XMLELEMENT (a, ',', a.c2) ORDER BY a.c2).EXTRACT ('//text()'), 2) AS c2 FROM t1 a GROUP BY a.c1; C1 C2 --- ------------ 1 01 2 02,03 3 04,04,05,06 3 rows selected.
④ 후임자를 괴롭히고 싶다면 MODEL 절을 사용해도 된다...--;
SELECT a.c1, RTRIM (a.c2, ',') as c2 FROM (SELECT c1, c2, rn FROM t1 a MODEL PARTITION BY (a.c1) DIMENSION BY (ROW_NUMBER() OVER (PARTITION BY a.c1 ORDER BY a.c2) AS rn) MEASURES (CAST (a.c2 AS VARCHAR2(4000)) AS c2) RULES (c2[ANY] ORDER BY rn DESC = c2[CV()] || ',' || c2[CV()+1])) a WHERE a.rn = 1 ORDER BY a.c1; C1 C2 --- ------------ 1 01 2 02,03 3 04,04,05,06 3 rows selected.
⑤ 9i에서는 전통적 방식인 ROW_NUMBER와 SYS_CONNECT_BY_PATH 조합을 사용하면 된다.
SELECT a.c1, SUBSTR (MAX (SYS_CONNECT_BY_PATH (a.c2, ',')), 2) AS c2 FROM (SELECT a.c1, a.c2, ROW_NUMBER () OVER (PARTITION BY a.c1 ORDER BY a.c2) AS rn FROM t1 a) a START WITH a.rn = 1 CONNECT BY a.c1 = PRIOR a.c1 AND a.rn - 1 = PRIOR a.rn GROUP BY a.c1 ORDER BY a.c1; C1 C2 --- ------------ 1 01 2 02,03 3 04,04,05,06 3 rows selected.
'Database > Oracle' 카테고리의 다른 글
ORACLE|오라클 유니코드 UTF-8 사용 (0) | 2016.02.17 |
---|---|
ORACLE|오라클 힌트(Hint) (0) | 2015.02.16 |
ORACLE|오라클 Pipelined Table Functions (0) | 2015.02.15 |
ORACLE|오라클 11g New Feature - Virtual Columns (가상 컬럼) (0) | 2014.12.02 |
ORACLE|오라클에서 숫자 한글(국문) 표기하기 (0) | 2014.11.27 |
Comments