๊ณ์ธตํ ์ฟผ๋ฆฌ
๊ณ์ธต์ ์ธ ๋ฐ์ดํฐ ๊ตฌ์กฐ์์ ๋ถ๋ชจ-์์ ๊ด๊ณ๋ฅผ ๊ฐ์ง ๋ฐ์ดํฐ๋ฅผ ๊ฒ์ํ๊ฑฐ๋ ์กฐ์ํ๋ ์ฟผ๋ฆฌ
๋ฌธ๋ฒ
SELECT [ํํ์๋ค]
FROM [ํ
์ด๋ธ๋ช
]
START WITH [์์ ์กฐ๊ฑด]
CONNECT BY [์ฌ๊ท ์กฐ๊ฑด];
SQL
๋ณต์ฌ
๊ธฐ๋ณธ ๊ตฌ์ฑ ์์
๊ตฌ๋ฌธ | ์ค๋ช
|
SELECT [ํํ์๋ค] | ์กฐํํ ์ด์ ์ง์ ํฉ๋๋ค.
๊ณ์ธต ๊ตฌ์กฐ๋ฅผ ํํํ๊ธฐ ์ํ ์ด๊ณผ ์ถ๊ฐ์ ์ธ ์ด์ด ํฌํจ๋ ์ ์์ต๋๋ค. |
FROM [ํ
์ด๋ธ๋ช
] | ๊ณ์ธตํ ์ฟผ๋ฆฌ๋ฅผ ์ํํ ๋์ ํ
์ด๋ธ์ ์ง์ ํฉ๋๋ค. |
START WITH [์์ ์กฐ๊ฑด] | ๊ณ์ธต ๊ตฌ์กฐ์ ์์์ ์ ์ ์ํฉ๋๋ค.
์ง์ ๋ ์กฐ๊ฑด์ ๋ง์กฑํ๋ ํ์ด ์์์ ์ด ๋ฉ๋๋ค. |
CONNECT BY [์ฌ๊ท ์กฐ๊ฑด] | ์ฌ๊ท์ ์ธ ๊ด๊ณ๋ฅผ ์ ์ํฉ๋๋ค.
์ง์ ๋ ์กฐ๊ฑด์ ๋ง์กฑํ๋ ํ์ด ์ด์ ํ๊ณผ ์ฐ๊ฒฐ๋์ด ๊ณ์ธต ๊ตฌ์กฐ๋ฅผ ํ์ฑํฉ๋๋ค. |
PRIOR | CONNECT BY ์ ๊ณผ ํจ๊ป ์ฌ์ฉ๋๋ฉฐ, ์ด์ ํ์ ์๋ฏธํ๋ ํค์๋์ด๋ค.
|
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์ ๋ฐํํฉ๋๋ค.



