Search
Duplicate

κ³„μΈ΅ν˜• 쿼리 CONNECT BY

κ³„μΈ΅ν˜• 쿼리

계측적인 데이터 κ΅¬μ‘°μ—μ„œ λΆ€λͺ¨-μžμ‹ 관계λ₯Ό κ°€μ§„ 데이터λ₯Ό κ²€μƒ‰ν•˜κ±°λ‚˜ μ‘°μž‘ν•˜λŠ” 쿼리
주둜 쑰직도, 트리 ꡬ쑰 데이터 등을 μ²˜λ¦¬ν•  λ•Œ μ‚¬μš©λ©λ‹ˆλ‹€.

문법

SELECT [ν‘œν˜„μ‹λ“€] FROM [ν…Œμ΄λΈ”λͺ…] START WITH [μ‹œμž‘ 쑰건] CONNECT BY [μž¬κ·€ 쑰건];
SQL
볡사

κΈ°λ³Έ ꡬ성 μš”μ†Œ

ꡬ문
μ„€λͺ…
SELECT [ν‘œν˜„μ‹λ“€]
μ‘°νšŒν•  열을 μ§€μ •ν•©λ‹ˆλ‹€. 계측 ꡬ쑰λ₯Ό ν‘œν˜„ν•˜κΈ° μœ„ν•œ μ—΄κ³Ό 좔가적인 열이 포함될 수 μžˆμŠ΅λ‹ˆλ‹€.
FROM [ν…Œμ΄λΈ”λͺ…]
κ³„μΈ΅ν˜• 쿼리λ₯Ό μˆ˜ν–‰ν•  λŒ€μƒ ν…Œμ΄λΈ”μ„ μ§€μ •ν•©λ‹ˆλ‹€.
START WITH [μ‹œμž‘ 쑰건]
계측 ꡬ쑰의 μ‹œμž‘μ μ„ μ •μ˜ν•©λ‹ˆλ‹€. μ§€μ •λœ 쑰건을 λ§Œμ‘±ν•˜λŠ” 행이 μ‹œμž‘μ μ΄ λ©λ‹ˆλ‹€.
CONNECT BY [μž¬κ·€ 쑰건]
μž¬κ·€μ μΈ 관계λ₯Ό μ •μ˜ν•©λ‹ˆλ‹€. μ§€μ •λœ 쑰건을 λ§Œμ‘±ν•˜λŠ” 행이 이전 ν–‰κ³Ό μ—°κ²°λ˜μ–΄ 계측 ꡬ쑰λ₯Ό ν˜•μ„±ν•©λ‹ˆλ‹€.
PRIOR
CONNECT BY 절과 ν•¨κ»˜ μ‚¬μš©λ˜λ©°, 이전 행을 μ˜λ―Έν•˜λŠ” ν‚€μ›Œλ“œμ΄λ‹€. PRIOR μžμ‹ = λΆ€λͺ¨ (μ •λ°©ν–₯) : λΆ€λͺ¨ μžμ‹ PRIOR λΆ€λͺ¨ = μžμ‹ (μ—­λ°©ν–₯) : μžμ‹ λΆ€λͺ¨

CONNECT BY ν‚€μ›Œλ“œ

ν‚€μ›Œλ“œ 및 ν•¨μˆ˜
μ„€λͺ…
CONNECT BY
계측적 쿼리λ₯Ό μ •μ˜ν•˜κΈ° μœ„ν•œ ν‚€μ›Œλ“œλ‘œ, λΆ€λͺ¨-μžμ‹ κ°„μ˜ 관계λ₯Ό μ§€μ •ν•©λ‹ˆλ‹€.
LEVEL
ν˜„μž¬ ν–‰μ˜ 계측 λ ˆλ²¨μ„ λ‚˜νƒ€λ‚΄λŠ” μ˜μ‚¬ μ—΄μž…λ‹ˆλ‹€.
CONNECT_BY_ROOT
계측 κ΅¬μ‘°μ—μ„œ μ΅œμƒμœ„ λΆ€λͺ¨λ₯Ό λ‚˜νƒ€λ‚΄λŠ” μ˜μ‚¬ μ—΄μž…λ‹ˆλ‹€.
CONNECT_BY_ISLEAF
ν˜„μž¬ 행이 리프(말단) λ…Έλ“œμΈμ§€ μ—¬λΆ€λ₯Ό νŒλ³„ν•˜λŠ” μ˜μ‚¬ μ—΄μž…λ‹ˆλ‹€.
SYS_CONNECT_BY_PATH
계측적 μΏΌλ¦¬μ—μ„œ ν–‰μ˜ 경둜λ₯Ό λ‚˜νƒ€λ‚΄λŠ” ν•¨μˆ˜μž…λ‹ˆλ‹€.
NOCYCLE
μˆœν™˜(cycle)을 λ°©μ§€ν•˜κΈ° μœ„ν•œ μ˜΅μ…˜μž…λ‹ˆλ‹€.
CONNECT_BY_ISCYCLE
ν˜„μž¬ 행이 μˆœν™˜ ꡬ쑰에 μžˆλŠ”μ§€ μ—¬λΆ€λ₯Ό νŒλ³„ν•˜λŠ” μ˜μ‚¬ μ—΄μž…λ‹ˆλ‹€.
ORDER BY SIBLINGS BY 컬럼
같은 LEVEL λ…Έλ“œ μ‚¬μ΄μ—μ„œ 정렬을 μˆ˜ν–‰ν•©λ‹ˆλ‹€.

κ³„μΈ΅ν˜• 쿼리둜 쑰직도λ₯Ό 좜λ ₯ν•˜λŠ” μ˜ˆμ‹œ μ½”λ“œ

SELECT LEVEL , employee_id , first_name , last_name , job_id , manager_id FROM employees START WITH manager_id IS NULL CONNECT BY PRIOR employee_id = manager_id;
SQL
볡사
β€’
START WITH manager_id IS NULL: μ΅œμƒμœ„ λΆ€μ„œμ˜ 직원듀을 μ„ νƒν•©λ‹ˆλ‹€. μ—¬κΈ°μ„œλŠ” μ΅œμƒμœ„ 직원이 λ§€λ‹ˆμ €κ°€ μ—†λŠ” μ§μ›λ“€μž…λ‹ˆλ‹€.
β€’
CONNECT BY PRIOR employee_id = manager_id: 각 행을 이전 ν–‰κ³Ό μ—°κ²°ν•©λ‹ˆλ‹€. 이전 ν–‰(PRIOR)의 employee_idκ°€ ν˜„μž¬ ν–‰μ˜ manager_id와 같은 경우, κ³„μΈ΅μ μœΌλ‘œ μ—°κ²°λ©λ‹ˆλ‹€.
β€’
LEVEL: 각 ν–‰μ˜ 계측 λ ˆλ²¨μ„ λ‚˜νƒ€λƒ…λ‹ˆλ‹€.
β—¦
1 : λŒ€ν‘œ
β—¦
2 : λΆ€μ„œμž₯ (상사)
β—¦
3 : 직원 (λΆ€ν•˜)

CONNECT BYλ₯Ό ν™œμš©ν•œ λŒ€λŒ“κΈ€ ꡬ쑰 μ˜ˆμ‹œ

λŒ€λŒ“κΈ€ ν…Œμ΄λΈ” 생성 및 μƒ˜ν”Œ 데이터

-- DDL CREATE TABLE board ( no NUMBER NOT NULL, title varchar2(100) NOT NULL, writer varchar2(100) NOT NULL, content varchar2(1000), reg_date DATE DEFAULT sysdate NOT NULL, upd_date DATE DEFAULT sysdate NOT NULL, views NUMBER DEFAULT 0 NOT NULL, PRIMARY KEY (no) ); CREATE TABLE comments ( comment_id NUMBER NOT NULL, board_no NUMBER NOT NULL, parent_comment_id NUMBER, writer VARCHAR2(100) NOT NULL, content VARCHAR2(1000) NOT NULL, reg_date DATE DEFAULT sysdate NOT NULL, PRIMARY KEY (comment_id), FOREIGN KEY (parent_comment_id) REFERENCES comments(comment_id) ); -- μƒ˜ν”Œ 데이터 INSERT INTO comments (comment_id, board_no, parent_comment_id, writer, content) VALUES (1, 1, NULL, 'μ‚¬μš©μž1', '첫 번째 λŒ“κΈ€μž…λ‹ˆλ‹€.'); INSERT INTO comments (comment_id, board_no, parent_comment_id, writer, content) VALUES (2, 1, 1, 'μ‚¬μš©μž2', '첫 번째 λŒ“κΈ€μ— λŒ€ν•œ λŒ€λŒ“κΈ€μž…λ‹ˆλ‹€.'); INSERT INTO comments (comment_id, board_no, parent_comment_id, writer, content) VALUES (3, 1, 1, 'μ‚¬μš©μž3', '첫 번째 λŒ“κΈ€μ— λŒ€ν•œ 또 λ‹€λ₯Έ λŒ€λŒ“κΈ€μž…λ‹ˆλ‹€.'); INSERT INTO comments (comment_id, board_no, parent_comment_id, writer, content) VALUES (4, 1, 2, 'μ‚¬μš©μž4', 'λŒ€λŒ“κΈ€μ— λŒ€ν•œ λŒ€λŒ“κΈ€μž…λ‹ˆλ‹€.'); INSERT INTO comments (comment_id, board_no, parent_comment_id, writer, content) VALUES (5, 1, NULL, 'μ‚¬μš©μž5', '두 번째 λŒ“κΈ€μž…λ‹ˆλ‹€.'); INSERT INTO comments (comment_id, board_no, parent_comment_id, writer, content) VALUES (6, 1, 5, 'μ‚¬μš©μž6', '두 번째 λŒ“κΈ€μ— λŒ€ν•œ λŒ€λŒ“κΈ€μž…λ‹ˆλ‹€.'); INSERT INTO comments (comment_id, board_no, parent_comment_id, writer, content) VALUES (7, 1, NULL, 'μ‚¬μš©μž7', 'μ„Έ 번째 λŒ“κΈ€μž…λ‹ˆλ‹€.'); INSERT INTO comments (comment_id, board_no, parent_comment_id, writer, content) VALUES (8, 1, 3, 'μ‚¬μš©μž8', '첫 번째 λŒ“κΈ€μ˜ λŒ€λŒ“κΈ€μ— λŒ€ν•œ λ‹΅κΈ€μž…λ‹ˆλ‹€.');
SQL
볡사

κ³„μΈ΅ν˜• 쿼리둜 λŒ€λŒ“κΈ€ ꡬ쑰 쑰회

SELECT LEVEL, LPAD(' ', (LEVEL-1)*4) || writer AS writer, comment_id, parent_comment_id, content, reg_date FROM comments WHERE board_no = 1 START WITH parent_comment_id IS NULL CONNECT BY PRIOR comment_id = parent_comment_id ORDER SIBLINGS BY comment_id;
SQL
볡사
β€’
START WITH parent_comment_id IS NULL: μ΅œμƒμœ„ λŒ“κΈ€(λΆ€λͺ¨ λŒ“κΈ€μ΄ μ—†λŠ” λŒ“κΈ€)을 μ‹œμž‘μ μœΌλ‘œ μ§€μ •ν•©λ‹ˆλ‹€.
β€’
CONNECT BY PRIOR comment_id = parent_comment_id: 이전 ν–‰μ˜ comment_idκ°€ ν˜„μž¬ ν–‰μ˜ parent_comment_id와 같은 경우 κ³„μΈ΅μ μœΌλ‘œ μ—°κ²°λ©λ‹ˆλ‹€.
β€’
LPAD(' ', (LEVEL-1)*4): 계측 λ ˆλ²¨μ— 따라 λ“€μ—¬μ“°κΈ°λ₯Ό μ μš©ν•˜μ—¬ λŒ€λŒ“κΈ€ ꡬ쑰λ₯Ό μ‹œκ°μ μœΌλ‘œ ν‘œν˜„ν•©λ‹ˆλ‹€.
β€’
ORDER SIBLINGS BY comment_id: 같은 레벨의 λŒ“κΈ€λ“€μ„ comment_id μˆœμ„œλ‘œ μ •λ ¬ν•©λ‹ˆλ‹€.

κ²°κ³Ό μ˜ˆμ‹œ

LEVEL
WRITER
COMMENT_ID
PARENT_COMMENT_ID
CONTENT
1
μ‚¬μš©μž1
1
NULL
첫 번째 λŒ“κΈ€μž…λ‹ˆλ‹€.
2
μ‚¬μš©μž2
2
1
첫 번째 λŒ“κΈ€μ— λŒ€ν•œ λŒ€λŒ“κΈ€μž…λ‹ˆλ‹€.
3
μ‚¬μš©μž4
4
2
λŒ€λŒ“κΈ€μ— λŒ€ν•œ λŒ€λŒ“κΈ€μž…λ‹ˆλ‹€.
2
μ‚¬μš©μž3
3
1
첫 번째 λŒ“κΈ€μ— λŒ€ν•œ 또 λ‹€λ₯Έ λŒ€λŒ“κΈ€μž…λ‹ˆλ‹€.
3
μ‚¬μš©μž8
8
3
첫 번째 λŒ“κΈ€μ˜ λŒ€λŒ“κΈ€μ— λŒ€ν•œ λ‹΅κΈ€μž…λ‹ˆλ‹€.
1
μ‚¬μš©μž5
5
NULL
두 번째 λŒ“κΈ€μž…λ‹ˆλ‹€.
2
μ‚¬μš©μž6
6
5
두 번째 λŒ“κΈ€μ— λŒ€ν•œ λŒ€λŒ“κΈ€μž…λ‹ˆλ‹€.
1
μ‚¬μš©μž7
7
NULL
μ„Έ 번째 λŒ“κΈ€μž…λ‹ˆλ‹€.

경둜 ν‘œμ‹œν•˜κΈ° (SYS_CONNECT_BY_PATH μ‚¬μš©)

SELECT LEVEL, comment_id, parent_comment_id, writer, content, SYS_CONNECT_BY_PATH(writer, ' β†’ ') AS path FROM comments WHERE board_no = 1 START WITH parent_comment_id IS NULL CONNECT BY PRIOR comment_id = parent_comment_id ORDER SIBLINGS BY comment_id;
SQL
볡사
β€’
SYS_CONNECT_BY_PATH(writer, ' β†’ '): 계측 ꡬ쑰의 경둜λ₯Ό ν‘œμ‹œν•©λ‹ˆλ‹€. μ΅œμƒμœ„ λŒ“κΈ€λΆ€ν„° ν˜„μž¬ λŒ“κΈ€κΉŒμ§€μ˜ μž‘μ„±μžλ₯Ό ν™”μ‚΄ν‘œλ‘œ μ—°κ²°ν•˜μ—¬ λ³΄μ—¬μ€λ‹ˆλ‹€.

루트 λŒ“κΈ€ 정보 κ°€μ Έμ˜€κΈ° (CONNECT_BY_ROOT μ‚¬μš©)

SELECT LEVEL, comment_id, parent_comment_id, writer, content, CONNECT_BY_ROOT comment_id AS root_comment_id, CONNECT_BY_ROOT writer AS root_writer FROM comments WHERE board_no = 1 START WITH parent_comment_id IS NULL CONNECT BY PRIOR comment_id = parent_comment_id ORDER SIBLINGS BY comment_id;
SQL
볡사
β€’
CONNECT_BY_ROOT comment_id: ν•΄λ‹Ή λŒ“κΈ€μ΄ μ†ν•œ μ΅œμƒμœ„ λŒ“κΈ€μ˜ IDλ₯Ό λ°˜ν™˜ν•©λ‹ˆλ‹€.
β€’
CONNECT_BY_ROOT writer: ν•΄λ‹Ή λŒ“κΈ€μ΄ μ†ν•œ μ΅œμƒμœ„ λŒ“κΈ€μ˜ μž‘μ„±μžλ₯Ό λ°˜ν™˜ν•©λ‹ˆλ‹€.

말단 λŒ“κΈ€ ν™•μΈν•˜κΈ° (CONNECT_BY_ISLEAF μ‚¬μš©)

SELECT LEVEL, comment_id, parent_comment_id, writer, content, CONNECT_BY_ISLEAF AS is_leaf FROM comments WHERE board_no = 1 START WITH parent_comment_id IS NULL CONNECT BY PRIOR comment_id = parent_comment_id ORDER SIBLINGS BY comment_id;
SQL
볡사
β€’
CONNECT_BY_ISLEAF: ν˜„μž¬ λŒ“κΈ€μ΄ 말단 λŒ“κΈ€(μžμ‹μ΄ μ—†λŠ” λŒ“κΈ€)인 경우 1을, κ·Έλ ‡μ§€ μ•ŠμœΌλ©΄ 0을 λ°˜ν™˜ν•©λ‹ˆλ‹€.