1-- =============================================================================
2-- PostgreSQL JOIN ์์
3-- Various Types of JOINs in PostgreSQL
4-- =============================================================================
5
6-- ๋จผ์ 01_basic_crud.sql์ ์คํํ์ฌ ํ
์ด๋ธ๊ณผ ๋ฐ์ดํฐ๋ฅผ ์์ฑํ์ธ์.
7
8-- =============================================================================
9-- ํ
์คํธ ๋ฐ์ดํฐ ์ถ๊ฐ
10-- =============================================================================
11
12-- ๋ถ์๊ฐ ์๋ ์ง์ ์ถ๊ฐ (NULL dept_id)
13INSERT INTO employees (first_name, last_name, email, salary, dept_id)
14VALUES ('๋ฌด์์', '์ง์', 'nodept@company.com', 40000, NULL);
15
16-- ์ง์์ด ์๋ ๋ถ์ ์ถ๊ฐ
17INSERT INTO departments (dept_name, location)
18VALUES ('Finance', 'Seoul');
19
20-- =============================================================================
21-- 1. INNER JOIN
22-- =============================================================================
23-- ์์ชฝ ํ
์ด๋ธ์์ ๋งค์นญ๋๋ ํ๋ง ๋ฐํ
24
25SELECT
26 e.emp_id,
27 e.first_name,
28 e.last_name,
29 e.salary,
30 d.dept_name,
31 d.location
32FROM employees e
33INNER JOIN departments d ON e.dept_id = d.dept_id;
34
35-- ํ
์ด๋ธ ๋ณ์นญ ์์ด
36SELECT
37 employees.first_name,
38 employees.last_name,
39 departments.dept_name
40FROM employees
41INNER JOIN departments ON employees.dept_id = departments.dept_id;
42
43-- =============================================================================
44-- 2. LEFT JOIN (LEFT OUTER JOIN)
45-- =============================================================================
46-- ์ผ์ชฝ ํ
์ด๋ธ์ ๋ชจ๋ ํ + ๋งค์นญ๋๋ ์ค๋ฅธ์ชฝ ํ
์ด๋ธ ํ
47
48SELECT
49 e.emp_id,
50 e.first_name,
51 e.last_name,
52 e.salary,
53 d.dept_name,
54 d.location
55FROM employees e
56LEFT JOIN departments d ON e.dept_id = d.dept_id;
57
58-- ๋ถ์๊ฐ ์๋ ์ง์๋ง
59SELECT
60 e.first_name,
61 e.last_name
62FROM employees e
63LEFT JOIN departments d ON e.dept_id = d.dept_id
64WHERE d.dept_id IS NULL;
65
66-- =============================================================================
67-- 3. RIGHT JOIN (RIGHT OUTER JOIN)
68-- =============================================================================
69-- ์ค๋ฅธ์ชฝ ํ
์ด๋ธ์ ๋ชจ๋ ํ + ๋งค์นญ๋๋ ์ผ์ชฝ ํ
์ด๋ธ ํ
70
71SELECT
72 e.emp_id,
73 e.first_name,
74 e.last_name,
75 d.dept_name,
76 d.location
77FROM employees e
78RIGHT JOIN departments d ON e.dept_id = d.dept_id;
79
80-- ์ง์์ด ์๋ ๋ถ์๋ง
81SELECT
82 d.dept_name,
83 d.location
84FROM employees e
85RIGHT JOIN departments d ON e.dept_id = d.dept_id
86WHERE e.emp_id IS NULL;
87
88-- =============================================================================
89-- 4. FULL OUTER JOIN
90-- =============================================================================
91-- ์์ชฝ ํ
์ด๋ธ์ ๋ชจ๋ ํ (๋งค์นญ๋์ง ์์ผ๋ฉด NULL)
92
93SELECT
94 e.emp_id,
95 e.first_name,
96 e.last_name,
97 d.dept_name,
98 d.location
99FROM employees e
100FULL OUTER JOIN departments d ON e.dept_id = d.dept_id;
101
102-- ๋งค์นญ๋์ง ์๋ ํ๋ง
103SELECT
104 e.emp_id,
105 e.first_name,
106 d.dept_name
107FROM employees e
108FULL OUTER JOIN departments d ON e.dept_id = d.dept_id
109WHERE e.emp_id IS NULL OR d.dept_id IS NULL;
110
111-- =============================================================================
112-- 5. CROSS JOIN (์นดํ
์์ ๊ณฑ)
113-- =============================================================================
114-- ๋ชจ๋ ๊ฐ๋ฅํ ์กฐํฉ
115
116SELECT
117 e.first_name,
118 d.dept_name
119FROM employees e
120CROSS JOIN departments d
121LIMIT 20;
122
123-- CROSS JOIN์ ON ์ ์์ด ์ฝค๋ง๋ก๋ ํํ ๊ฐ๋ฅ
124SELECT
125 e.first_name,
126 d.dept_name
127FROM employees e, departments d
128WHERE e.dept_id IS NOT NULL
129LIMIT 20;
130
131-- =============================================================================
132-- 6. SELF JOIN
133-- =============================================================================
134-- ๊ฐ์ ํ
์ด๋ธ์ ์๊ธฐ ์์ ๊ณผ ์กฐ์ธ
135
136-- ์์ ๋ฅผ ์ํ ๊ด๋ฆฌ์ ์ปฌ๋ผ ์ถ๊ฐ
137ALTER TABLE employees ADD COLUMN IF NOT EXISTS manager_id INTEGER REFERENCES employees(emp_id);
138
139-- ์ผ๋ถ ์ง์์๊ฒ ๊ด๋ฆฌ์ ์ง์
140UPDATE employees SET manager_id = 4 WHERE emp_id IN (1, 2);
141UPDATE employees SET manager_id = 1 WHERE emp_id IN (5, 6);
142
143-- ์ง์๊ณผ ๊ด๋ฆฌ์ ์กฐํ
144SELECT
145 e.emp_id,
146 e.first_name || ' ' || e.last_name AS employee_name,
147 m.first_name || ' ' || m.last_name AS manager_name
148FROM employees e
149LEFT JOIN employees m ON e.manager_id = m.emp_id;
150
151-- =============================================================================
152-- 7. ๋ค์ค ํ
์ด๋ธ JOIN
153-- =============================================================================
154
155-- ํ๋ก์ ํธ ํ
์ด๋ธ ์์ฑ
156DROP TABLE IF EXISTS projects CASCADE;
157DROP TABLE IF EXISTS employee_projects CASCADE;
158
159CREATE TABLE projects (
160 project_id SERIAL PRIMARY KEY,
161 project_name VARCHAR(100) NOT NULL,
162 start_date DATE,
163 end_date DATE,
164 budget NUMERIC(12, 2)
165);
166
167-- ์ง์-ํ๋ก์ ํธ ์ฐ๊ฒฐ ํ
์ด๋ธ (๋ค๋๋ค ๊ด๊ณ)
168CREATE TABLE employee_projects (
169 emp_id INTEGER REFERENCES employees(emp_id),
170 project_id INTEGER REFERENCES projects(project_id),
171 role VARCHAR(50),
172 PRIMARY KEY (emp_id, project_id)
173);
174
175-- ๋ฐ์ดํฐ ์ฝ์
176INSERT INTO projects (project_name, start_date, end_date, budget)
177VALUES
178 ('์น์ฌ์ดํธ ๋ฆฌ๋ด์ผ', '2024-01-01', '2024-06-30', 100000),
179 ('๋ชจ๋ฐ์ผ ์ฑ ๊ฐ๋ฐ', '2024-03-01', '2024-12-31', 200000),
180 ('๋ฐ์ดํฐ ๋ถ์ ํ๋ซํผ', '2024-02-01', '2024-08-31', 150000);
181
182INSERT INTO employee_projects (emp_id, project_id, role)
183VALUES
184 (1, 1, 'Lead'),
185 (2, 1, 'Developer'),
186 (1, 2, 'Developer'),
187 (3, 2, 'Lead'),
188 (4, 3, 'Lead'),
189 (2, 3, 'Analyst');
190
191-- 3๊ฐ ํ
์ด๋ธ ์กฐ์ธ: ์ง์ + ๋ถ์ + ํ๋ก์ ํธ
192SELECT
193 e.first_name || ' ' || e.last_name AS employee_name,
194 d.dept_name,
195 p.project_name,
196 ep.role
197FROM employees e
198JOIN departments d ON e.dept_id = d.dept_id
199JOIN employee_projects ep ON e.emp_id = ep.emp_id
200JOIN projects p ON ep.project_id = p.project_id
201ORDER BY e.first_name, p.project_name;
202
203-- =============================================================================
204-- 8. NATURAL JOIN
205-- =============================================================================
206-- ๊ฐ์ ์ด๋ฆ์ ์ปฌ๋ผ์ผ๋ก ์๋ ์กฐ์ธ (์ฌ์ฉ ๋น๊ถ์ฅ - ๋ช
์์ ON ์ ๊ถ์ฅ)
207
208-- dept_id๊ฐ ๊ฐ์ ์ด๋ฆ์ด๋ฏ๋ก ์๋ ๋งค์นญ
209-- SELECT * FROM employees NATURAL JOIN departments;
210
211-- =============================================================================
212-- 9. USING ์
213-- =============================================================================
214-- ๊ฐ์ ์ด๋ฆ์ ์ปฌ๋ผ์ด ์์ ๋ ON ๋์ ์ฌ์ฉ
215
216SELECT
217 e.first_name,
218 e.last_name,
219 d.dept_name
220FROM employees e
221JOIN departments d USING (dept_id);
222
223-- =============================================================================
224-- 10. ์กฐ์ธ + ์ง๊ณ
225-- =============================================================================
226
227-- ๋ถ์๋ณ ์ง์ ์์ ํ๊ท ๊ธ์ฌ
228SELECT
229 d.dept_name,
230 COUNT(e.emp_id) AS employee_count,
231 ROUND(AVG(e.salary), 2) AS avg_salary,
232 MIN(e.salary) AS min_salary,
233 MAX(e.salary) AS max_salary
234FROM departments d
235LEFT JOIN employees e ON d.dept_id = e.dept_id
236GROUP BY d.dept_id, d.dept_name
237ORDER BY employee_count DESC;
238
239-- ํ๋ก์ ํธ๋ณ ์ฐธ์ฌ ์ง์ ์
240SELECT
241 p.project_name,
242 COUNT(ep.emp_id) AS member_count,
243 p.budget
244FROM projects p
245LEFT JOIN employee_projects ep ON p.project_id = ep.project_id
246GROUP BY p.project_id, p.project_name, p.budget
247ORDER BY member_count DESC;
248
249-- =============================================================================
250-- 11. ์กฐ์ธ ์ฑ๋ฅ ํ
251-- =============================================================================
252
253-- ์กฐ์ธ์ ์ฌ์ฉ๋๋ ์ปฌ๋ผ์ ์ธ๋ฑ์ค๊ฐ ์๋์ง ํ์ธ
254-- CREATE INDEX idx_employees_dept ON employees(dept_id);
255-- CREATE INDEX idx_employee_projects_emp ON employee_projects(emp_id);
256-- CREATE INDEX idx_employee_projects_proj ON employee_projects(project_id);
257
258-- ์คํ ๊ณํ ํ์ธ
259EXPLAIN ANALYZE
260SELECT
261 e.first_name,
262 d.dept_name
263FROM employees e
264JOIN departments d ON e.dept_id = d.dept_id;
265
266-- =============================================================================
267-- JOIN ์ ํ ์์ฝ
268-- =============================================================================
269/*
270| JOIN ์ ํ | ์ค๋ช
|
271|-----------------|-------------------------------------------|
272| INNER JOIN | ์์ชฝ ๋ชจ๋ ๋งค์นญ๋๋ ํ๋ง |
273| LEFT JOIN | ์ผ์ชฝ ํ
์ด๋ธ ์ ์ฒด + ๋งค์นญ๋๋ ์ค๋ฅธ์ชฝ |
274| RIGHT JOIN | ์ค๋ฅธ์ชฝ ํ
์ด๋ธ ์ ์ฒด + ๋งค์นญ๋๋ ์ผ์ชฝ |
275| FULL OUTER JOIN | ์์ชฝ ํ
์ด๋ธ ์ ์ฒด |
276| CROSS JOIN | ๋ชจ๋ ๊ฐ๋ฅํ ์กฐํฉ (์นดํ
์์ ๊ณฑ) |
277| SELF JOIN | ๊ฐ์ ํ
์ด๋ธ๋ผ๋ฆฌ ์กฐ์ธ |
278
279ํ:
280- ํญ์ ON ์ ์ ๋ช
์์ ์ผ๋ก ์์ฑ
281- ์กฐ์ธ ์ปฌ๋ผ์ ์ธ๋ฑ์ค ์์ฑ
282- EXPLAIN์ผ๋ก ์คํ ๊ณํ ํ์ธ
283- ๋ถํ์ํ CROSS JOIN ํผํ๊ธฐ
284*/