검색결과 리스트
글
!markdown
# Oracle (오라클)
`계층구조`의 테이블의 데이터를 파악하고 싶다면, 오라클의 다음 문법을 사용해보자. `Oracle 8i`부터 지원한다고 하니 `호환성`도 좋다.
- START WITH
- CONNECT BY PRIOR
## 계층형 구조 쿼리 만들기
### 1. 테스트 데이터
설명하기에 앞서서 Oracle의 `DUAL`을 이용하여 다음과 같이 `테스트 데이터`를 만들었다.
아이디 값(`THIS_ID`)과 이름(`THIS_NAME`) 그리고 나를 포함하고 있는 상위의 아이디(`PARENT_ID`)까지 컬럼이 3개인 가상 테이블을 만들어서 테스트해 보자.
```sql
--------------------
-- 테스트 데이터
--------------------
SELECT 0 as THIS_ID, '루트' as THIS_NAME, null PARENT_ID FROM DUAL
UNION
SELECT 1 as THIS_ID, '1뎁스-1' as THIS_NAME, 0 PARENT_ID FROM DUAL
UNION
SELECT 2 as THIS_ID, '1뎁스-2' as THIS_NAME, 0 PARENT_ID FROM DUAL
UNION
SELECT 3 as THIS_ID, '2뎁스-1' as THIS_NAME, 1 PARENT_ID FROM DUAL
UNION
SELECT 4 as THIS_ID, '2뎁스-2' as THIS_NAME, 1 PARENT_ID FROM DUAL
UNION
SELECT 5 as THIS_ID, '2뎁스-3' as THIS_NAME, 2 PARENT_ID FROM DUAL
```
### 2. START WITH와 CONNECT BY PRIOR
`START WITH`와 `CONNECT BY PRIOR`를 설정하면 각 ROW마다 `계층구조를 알수 있는 데이터`를 활용할 수 있다.
더불어서 `LEVEL`컬럼의 값을 사용할 수 있는데, 이를 활용하면 `계층깊이 만큼의 수치`를 얻을 수 있다.
```sql
--------------------
-- 모든 계층구조 파악하기
--------------------
SELECT THIS_ID,
PARENT_ID,
LEVEL,
LPAD(' └', 2*(LEVEL-1)) || THIS_NAME CONTAINER_NAME_IMAGE
FROM (
SELECT 0 as THIS_ID, '루트' as THIS_NAME, null PARENT_ID FROM DUAL
UNION
SELECT 1 as THIS_ID, '1뎁스-1' as THIS_NAME, 0 PARENT_ID FROM DUAL
UNION
SELECT 2 as THIS_ID, '1뎁스-2' as THIS_NAME, 0 PARENT_ID FROM DUAL
UNION
SELECT 3 as THIS_ID, '2뎁스-1' as THIS_NAME, 1 PARENT_ID FROM DUAL
UNION
SELECT 4 as THIS_ID, '2뎁스-2' as THIS_NAME, 1 PARENT_ID FROM DUAL
UNION
SELECT 5 as THIS_ID, '2뎁스-3' as THIS_NAME, 2 PARENT_ID FROM DUAL
) TEST_DATA
START WITH PARENT_ID IS NULL
CONNECT BY PRIOR THIS_ID = PARENT_ID
```
### 3. CONNECT_BY_ROOT
`CONNECT_BY_ROOT`를 이용하면 해당 ROW마다 `가장 최상위 계층의 데이터`(ROOT 데이터)를 활용할 수 있다.
```sql
--------------------
-- 모든 계층구조 파악하기
-- - 항목별로 루트정보도 포함
--------------------
SELECT THIS_ID,
PARENT_ID,
LEVEL,
LPAD(' └', 2*(LEVEL-1)) || THIS_NAME CONTAINER_NAME_IMAGE,
CONNECT_BY_ROOT THIS_ID AS ROOT_ID,
CONNECT_BY_ROOT THIS_NAME AS ROOT_NAME
FROM (
SELECT 0 as THIS_ID, '루트' as THIS_NAME, null PARENT_ID FROM DUAL
UNION
SELECT 1 as THIS_ID, '1뎁스-1' as THIS_NAME, 0 PARENT_ID FROM DUAL
UNION
SELECT 2 as THIS_ID, '1뎁스-2' as THIS_NAME, 0 PARENT_ID FROM DUAL
UNION
SELECT 3 as THIS_ID, '2뎁스-1' as THIS_NAME, 1 PARENT_ID FROM DUAL
UNION
SELECT 4 as THIS_ID, '2뎁스-2' as THIS_NAME, 1 PARENT_ID FROM DUAL
UNION
SELECT 5 as THIS_ID, '2뎁스-3' as THIS_NAME, 2 PARENT_ID FROM DUAL
) TEST_DATA
START WITH PARENT_ID IS NULL
CONNECT BY PRIOR THIS_ID = PARENT_ID
```
그 밖에도 다음을 활용할 수 있다.
### 4. CONNECT_BY_ISLEAF
`CONNECT_BY_ISLEAF`를 이용하여 자식ROW 존재 여부
### 5. CONNECT_BY_ISCYCLE
`CONNECT_BY_ISCYCLE`를 이용하여 계층구조가 다시 자신에게 돌아오는 무한 뺑뺑이(?) 구조인지 여부
### 6. SYS_CONNECT_BY_PATH
`SYS_CONNECT_BY_PATH`를 이용하여 파일시스템 폴더 구조처럼 출력
### 참고
- [오라클] 계층형 쿼리 ( START WITH ... CONNECT BY ): [https://m.blog.naver.com/PostView.nhn?blogId=javaking75&logNo=220010288704&proxyReferer=https%3A%2F%2Fwww.google.co.kr%2F](https://m.blog.naver.com/PostView.nhn?blogId=javaking75&logNo=220010288704&proxyReferer=https%3A%2F%2Fwww.google.co.kr%2F)
- [oracle] CONNECT_BY_ROOT - 최상위 루트노드 찾기: [http://devjhs.tistory.com/166](http://devjhs.tistory.com/166)
'TOOL > DATABASE' 카테고리의 다른 글
[PostgreSQL] 예제 - 접속 및 확인 (0) | 2019.12.20 |
---|---|
[MySQL] 5.5이하 버전은 트랜젝션이 없다.??? (0) | 2018.12.03 |
[Oracle] DB_USER마다 Session을 제한하기 (0) | 2017.05.30 |
[Oracle] 계정(ACCOUNT) 암호만료(EXPIRED), 잠김(LOCK) 대처 (0) | 2017.04.06 |
[Oracle] 쉼표(,) 구분자로 목록화(리스팅)된 문자열에 포함한 컬럼의 행(row)만 출력하기 (0) | 2017.03.15 |