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์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.