์ต๊ทผ์ WITH์ ๊ณผ ์์ํ
์๋ธ์ ์ฐจ์ด๋ฅผ ์ฐพ๋ค๊ฐ ๋ฌธ๋ CTE๋ผ๋ ๊ฐ๋
์ ์ ํ๊ฒ ๋์๋ค.
CTE๋ ๋ฌด์์ด๋ฉฐ, WITH์ ๊ณผ CTE๋ ๋ฌด์จ ๊ด๊ณ๊ฐ ์๋๊ฑธ๊น?
์ค๋ ํฌ์คํ
์์ ์์ธํ ์์๋ณด์.
CTE๋ Common Table Expressions์ ์ฝ์์ด๋ค. CTE๋ SELECT, INSERT , UPDATE, DELETE์์ ์ฐธ์กฐ๊ฐ ๊ฐ๋ฅํ ์์์ ๊ฒฐ๊ณผ๊ฐ์ด๋ค.
์กฐ๊ธ ๋ ํ์ด ์ค๋ช ํ๋ฉด, SELECT, INSERT , UPDATE, DELETE ์ฟผ๋ฆฌ๋ฅผ ์คํํ ๋, ํด๋น ์ฟผ๋ฆฌ ๋ด๋ถ์์ CTE๋ฅผ ์ฌ์ฉํ ์ ์์ผ๋ฉฐ, ์ด๋ ํ ์ด๋ธ์ฒ๋ผ ์๊ตฌ์ ์ผ๋ก ์ ์ฅ๋๋๊ฒ ์๋ ์ฟผ๋ฆฌ๊ฐ ์คํ๋๋ ๋์์๋ง ์์๋ก ์กด์ฌํ๋ ๊ฒฐ๊ณผ๊ฐ์ด๋ค. ๋ํ CTE๋ ์์ ๊ฒฐ๊ณผ๊ฐ์ด๊ธฐ ๋๋ฌธ์ ํญ์ ๊ฒฐ๊ณผ๊ฐ์ ๋ฐํํ๋ค.
CTE๋ ํฌ๊ณ ๋ณต์กํ ์ฟผ๋ฆฌ๋ฅผ ๋จ์ํ์ํค๋๋ฐ ์ ์ฉํ๋ฉฐ, ์๊ณ ๋๋ ๊ณ์ธต์ด ์๋ ๋ฐ์ดํฐ๋ฅผ ์กฐ์ํ๋๋ฐ ์ด์ ์ด ์๋ค.
์ข ๋ฅ๋ก๋ ์๋ ๋ ๊ฐ์ง๊ฐ ์๋ค.
์ด๋ฒ ํฌ์คํ ์ CTE์ ์ ๋ฐ์ ์ธ ๋ด์ฉ์ ๋ํด ์์๋ณด๊ธฐ ์ํด ๋น์ฌ๊ท์ CTE๋ฅผ ์ฃผ๋ก ๋ค๋ฃจ๊ณ ์ ํ๋ค.
CTE๋ WITH์ ์ ํตํด ์ ์ํ ์ ์์ผ๋ฉฐ, ์ฌ์ฉ ๋ฐฉ๋ฒ์ ์๋์์ ์์ธํ ๋ค๋ค๋ณด๊ณ ์ ํ๋ค.
WITH [RECURSIVE]
cte_name [(col_name [, col_name] ...)] AS (subquery)
[, cte_name [(col_name [, col_name] ...)] AS (subquery)] ...
WITH
cte1 AS (SELECT a, b FROM table1),
cte2 AS (SELECT c, d FROM table2)
SELECT b, d FROM cte1 JOIN cte2
WHERE cte1.a = cte2.c;
CTE๋ฅผ ์ ์ํ๋ ๋ฐฉ๋ฒ์ ์๋์ ๊ฐ๋ค.
CTE๋ฅผ ์ ์ํ๊ณ ๋๋ฉด, DML์์ ์ํ๋ ์์น, ์ํ๋ ๋งํผ ์ฌ๋ฌ๋ฒ ์ฌ์ฉ ๊ฐ๋ฅํ๋ค.
# ํ์ ํ
์ด๋ธ
CREATE TABLE STUDENT_MAST (
STUDENT_ID VARCHAR(30) PRIMARY KEY
, STUDENT_NAME VARCHAR(10)
, CLASS_ID VARCHAR(30)
);
# ๊ต์ค ํ
์ด๋ธ
CREATE TABLE CLASS_ROOM_MAST (
CLASS_ID VARCHAR(30) PRIMARY KEY
, CLASS_NAME VARCHAR(10)
);
# ์ฑ์ ํ
์ด๋ธ
CREATE TABLE EXAM_GRADE (
STUDENT_ID VARCHAR(30) PRIMARY KEY
, GRADE INT
);
# ๊ต์ค ๋ฐ์ดํฐ ์ธํ
INSERT INTO CLASS_ROOM_MAST (CLASS_ID, CLASS_NAME) VALUES ('C01', '1๋ฐ');
INSERT INTO CLASS_ROOM_MAST (CLASS_ID, CLASS_NAME) VALUES ('C02', '2๋ฐ');
INSERT INTO CLASS_ROOM_MAST (CLASS_ID, CLASS_NAME) VALUES ('C03', '3๋ฐ');
# ํ์ ๋ฐ์ดํฐ ์ธํ
INSERT INTO STUDENT_MAST (STUDENT_ID, STUDENT_NAME, CLASS_ID) VALUES ('S01', '๊ฐ๋์', 'C01');
INSERT INTO STUDENT_MAST (STUDENT_ID, STUDENT_NAME, CLASS_ID) VALUES ('S02', '์ ์งํ', 'C01');
INSERT INTO STUDENT_MAST (STUDENT_ID, STUDENT_NAME, CLASS_ID) VALUES ('S03', '์ด๋์ฑ', 'C01');
INSERT INTO STUDENT_MAST (STUDENT_ID, STUDENT_NAME, CLASS_ID) VALUES ('S04', '์ก์ฑ์ฌ', 'C01');
INSERT INTO STUDENT_MAST (STUDENT_ID, STUDENT_NAME, CLASS_ID) VALUES ('S05', '์ ๋ฏผ์', 'C01');
INSERT INTO STUDENT_MAST (STUDENT_ID, STUDENT_NAME, CLASS_ID) VALUES ('S06', 'ํ์งํ', 'C02');
INSERT INTO STUDENT_MAST (STUDENT_ID, STUDENT_NAME, CLASS_ID) VALUES ('S07', '์ด์ ํ', 'C02');
INSERT INTO STUDENT_MAST (STUDENT_ID, STUDENT_NAME, CLASS_ID) VALUES ('S08', 'ํ์ํฌ', 'C02');
INSERT INTO STUDENT_MAST (STUDENT_ID, STUDENT_NAME, CLASS_ID) VALUES ('S09', '๊น๊ฐ์ฐ', 'C02');
INSERT INTO STUDENT_MAST (STUDENT_ID, STUDENT_NAME, CLASS_ID) VALUES ('S10', 'ํ๊ฐ์ธ', 'C02');
INSERT INTO STUDENT_MAST (STUDENT_ID, STUDENT_NAME, CLASS_ID) VALUES ('S11', '์ฃผ์ค๋ฐ', 'C03');
INSERT INTO STUDENT_MAST (STUDENT_ID, STUDENT_NAME, CLASS_ID) VALUES ('S12', '์ฅ๊ตญ์', 'C03');
INSERT INTO STUDENT_MAST (STUDENT_ID, STUDENT_NAME, CLASS_ID) VALUES ('S13', '๊น๋๊ฐ', 'C03');
INSERT INTO STUDENT_MAST (STUDENT_ID, STUDENT_NAME, CLASS_ID) VALUES ('S14', '๊ฐ์ง๋', 'C03');
INSERT INTO STUDENT_MAST (STUDENT_ID, STUDENT_NAME, CLASS_ID) VALUES ('S15', '์๋๋ฅ', 'C03');
# ์ฑ์ ๋ฐ์ดํฐ ์ธํ
INSERT INTO EXAM_GRADE (STUDENT_ID, GRADE) VALUES ('S01', 81);
INSERT INTO EXAM_GRADE (STUDENT_ID, GRADE) VALUES ('S02', 90);
INSERT INTO EXAM_GRADE (STUDENT_ID, GRADE) VALUES ('S03', 75);
INSERT INTO EXAM_GRADE (STUDENT_ID, GRADE) VALUES ('S04', 100);
INSERT INTO EXAM_GRADE (STUDENT_ID, GRADE) VALUES ('S05', 87);
INSERT INTO EXAM_GRADE (STUDENT_ID, GRADE) VALUES ('S06', 98);
INSERT INTO EXAM_GRADE (STUDENT_ID, GRADE) VALUES ('S07', 70);
INSERT INTO EXAM_GRADE (STUDENT_ID, GRADE) VALUES ('S08', 71);
INSERT INTO EXAM_GRADE (STUDENT_ID, GRADE) VALUES ('S09', 65);
INSERT INTO EXAM_GRADE (STUDENT_ID, GRADE) VALUES ('S10', 90);
INSERT INTO EXAM_GRADE (STUDENT_ID, GRADE) VALUES ('S11', 60);
INSERT INTO EXAM_GRADE (STUDENT_ID, GRADE) VALUES ('S12', 70);
INSERT INTO EXAM_GRADE (STUDENT_ID, GRADE) VALUES ('S13', 100);
INSERT INTO EXAM_GRADE (STUDENT_ID, GRADE) VALUES ('S14', 87);
INSERT INTO EXAM_GRADE (STUDENT_ID, GRADE) VALUES ('S15', 73);
# ๋ชจ๋ ํ
์ด๋ธ ์ ๋ฆฌ
# DROP TABLE STUDENT_MAST, CLASS_ROOM_MAST, EXAM_GRADE;
SELECT VSM.CLASS_NAME
, VSM.STUDENT_NAME
, VSM.GRADE
FROM (
SELECT CRM.CLASS_NAME
, CRM.CLASS_ID
, SM.STUDENT_ID
, SM.STUDENT_NAME
, ER.GRADE
, RANK() OVER(PARTITION BY SM.CLASS_ID ORDER BY ER.GRADE DESC) AS RANK_BY_CLASS
FROM STUDENT_MAST SM
INNER JOIN CLASS_ROOM_MAST CRM
ON SM.CLASS_ID = CRM.CLASS_ID
INNER JOIN EXAM_GRADE ER
ON SM.STUDENT_ID = ER.STUDENT_ID
) VSM
WHERE RANK_BY_CLASS = 1
ORDER BY VSM.CLASS_ID ASC
;
# CTE ์ ์
WITH STUDENT_RANK AS (
SELECT CRM.CLASS_NAME
, CRM.CLASS_ID
, SM.STUDENT_ID
, SM.STUDENT_NAME
, ER.GRADE
, RANK() OVER(PARTITION BY SM.CLASS_ID ORDER BY ER.GRADE DESC) AS RANK_BY_CLASS
FROM STUDENT_MAST SM
INNER JOIN CLASS_ROOM_MAST CRM
ON SM.CLASS_ID = CRM.CLASS_ID
INNER JOIN EXAM_GRADE ER
ON SM.STUDENT_ID = ER.STUDENT_ID
)
# CTE ์ฌ์ฉ
SELECT SR.CLASS_NAME
, SR.STUDENT_NAME
, SR.GRADE
FROM STUDENT_RANK SR
WHERE SR.RANK_BY_CLASS = 1
ORDER BY SR.CLASS_ID ASC
;