๐ ๊ณ์ธตํ ์ง์(Hierarchical Query)๋?
- SQL์์ ํ ์ด๋ธ ๋ด์ ๊ณ์ธต ๊ตฌ์กฐ๋ฅผ ํํํ ๋ ์ฌ์ฉํ๋ ๊ธฐ๋ฒ์ ๋๋ค.
- ๊ณ์ธต ๊ตฌ์กฐ๋ ์ผ๋ฐ์ ์ผ๋ก ๋ถ๋ชจ-์์ ๊ด๊ณ๋ก ์ด๋ฃจ์ด์ง ๋ฐ์ดํฐ๋ฅผ ๋ค๋ฃฐ ๋ ์ ์ฉํฉ๋๋ค. ์๋ฅผ ๋ค์ด, ํ์ฌ์ ์กฐ์ง๋์์๋ ๋ถ์๊ฐ ์์ ๋ ธ๋(๋ถ๋ชจ)๊ฐ ๋๊ณ , ํ์ ๋ถ์๋ ์ง์์ด ํ์ ๋ ธ๋(์์)๊ฐ ๋ฉ๋๋ค.
- ๊ณ์ธตํ ์ง์์์๋ ๊ฐ ํ์ด ์ํ ๊ณ์ธต์ ๊น์ด๋ฅผ ๋ํ๋ด๋ `LEVEL`์ด๋ผ๋ ๊ฐ์ ์ปฌ๋ผ์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
- ๋ฃจํธ ๋ ธ๋๋ 1๋ก ์์ํ๋ฉฐ, ์์ ๋ ธ๋๋ก ๋ด๋ ค๊ฐ์๋ก ๊ฐ์ด ์ฆ๊ฐํฉ๋๋ค.
- ์ฃผ์์ฌํญ
- ๊ณ์ธตํ ์ง์๋ Oracle์์๋ง ์ง์๋ฉ๋๋ค. ๋ค๋ฅธ ๋ฐ์ดํฐ๋ฒ ์ด์ค(PostgreSQL, MySQL ๋ฑ)์์๋ WITH RECURSIVE์ ๊ฐ์ ๋์ฒด ๋ฐฉ์์ ์ฌ์ฉํ์ฌ ๋น์ทํ ๊ฒฐ๊ณผ๋ฅผ ์ป์ ์ ์์ต๋๋ค.
๐ ๊ณ์ธตํ ์ง์ ๊ธฐ๋ณธ ๋ฌธ๋ฒ
SELECT ์ปฌ๋ผ๋ช
, LEVEL
FROM ํ
์ด๋ธ๋ช
START WITH ์กฐ๊ฑด -- 1๏ธโฃ ๊ณ์ธต ๊ตฌ์กฐ์ ์์์ ์ ์
CONNECT BY PRIOR ๋ถ๋ชจ์ปฌ๋ผ = ์์์ปฌ๋ผ -- 2๏ธโฃ ๋ถ๋ชจ-์์ ๊ด๊ณ ์ค์ โจ
ORDER SIBLINGS BY ์ ๋ ฌ์ปฌ๋ผ; -- 3๏ธโฃ ํ์ ๋
ธ๋ ์ ๋ ฌ
- `START WITH`์ : ๊ณ์ธต ๊ตฌ์กฐ์ ๋ฃจํธ ๋ ธ๋๋ฅผ ์ง์ ํ๋ฉฐ, ํด๋น ์กฐ๊ฑด์ ๋ง๋ ํ์ด ์์์ ์ด ๋ฉ๋๋ค.
- `CONNECT BY`์ : `PRIOR` ํค์๋๋ฅผ ์ฌ์ฉํ์ฌ ๋ถ๋ชจ์ ์์ ๊ฐ์ ๊ด๊ณ๋ฅผ ์ค์ ํฉ๋๋ค.
- `ORDER SIBLINGS BY`์ : ๊ฐ์ ๋ถ๋ชจ๋ฅผ ๊ฐ์ง ํ์ ๋ ธ๋๋ค์ ์ง์ ๋ ์ปฌ๋ผ์ผ๋ก ์ ๋ ฌํฉ๋๋ค.
๐ PRIOR ํค์๋
- ์ด ํค์๋๋ ํ์ฌ ํ์ ๋ถ๋ชจ ํ(๋ถ๋ชจ ๋ ธ๋)๋ฅผ ๋ํ๋ ๋๋ค.
- `CONNECT BY`, `SELECT`, `WHERE` ์ ์์ ์ฌ์ฉ๋ฉ๋๋ค.
โ๏ธ`CONNECT BY PRIOR ์์์ปฌ๋ผ = ๋ถ๋ชจ์ปฌ๋ผ` : ๋ถ๋ชจ → ์์ ์๋ฐฉํฅ ์ ๊ฐ
-- ์์ : ๋ถ์ ID๊ฐ 1์ธ ์ธ์ฌ๋ถ์ ํ์ ๋ถ์ ์กฐํโจ
SELECT department_name, LEVEL
FROM departments
START WITH department_id = 1 -- ๋ถ๋ชจ๊ฐ 1์ธ ๋ถ์ ์ฐพ๊ธฐ (์ธ์ฌ๋ถ)
CONNECT BY PRIOR department_id = parent_id; -- ๋ถ๋ชจ → ์์ ๊ด๊ณ ์ค์
-- ์ด ๊ตฌ๋ฌธ์ ๋ถ๋ชจ์ department_id์ ์์์ parent_id๋ฅผ ๋น๊ตํ์ฌ ๋ถ๋ชจ์์ ์์์ผ๋ก ํ์ํฉ๋๋ค.
โ๏ธ`CONNECT BY PRIOR ๋ถ๋ชจ์ปฌ๋ผ = ์์์ปฌ๋ผ` : ์์ → ๋ถ๋ชจ ์ญ๋ฐฉํฅ ์ ๊ฐ
-- ์์ : ๋ถ์ ID๊ฐ 4์ธ ๊ฐ๋ฐ๋ถ์ ์์ ๋ถ์ ์กฐํโจ
SELECT department_name, LEVEL
FROM departments
START WITH department_id = 4 -- ์์์ด 4์ธ ๋ถ์ ์ฐพ๊ธฐ (๊ฐ๋ฐ๋ถ)
CONNECT BY PRIOR parent_id = department_id; -- ์์ → ๋ถ๋ชจ ๊ด๊ณ ์ค์
-- ์ด ๊ตฌ๋ฌธ์ ํ์ฌ ํ์ parent_id์ ์ด์ ๋จ๊ณ์์ ๊ฐ์ ธ์จ ๋ถ๋ชจ์ department_id๋ฅผ ๋น๊ตํ์ฌ ์์ ๋ถ์๋ฅผ ์ฐพ์ต๋๋ค.