| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 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
- 에러
- 톰캣
- 튜닝
- 오라클
- oracle
- 오류
- Excel
- 엑셀
- 마이플랫폼
- 성능
- java
- 도서
- DB
- Tomcat
- MIP
- 이클립스
- 태그를 입력해 주세요.
- Eclipse
- 자바
- JEUS
- 함수
- 한글
- Book
- error
- JavaScript
- 회계
- 데이터베이스
- 기타소득
- Report Designer
- miplatform
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