02_joins.sql

Download
sql 285 lines 8.9 KB
  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*/