[MySQL] ์„œ๋ธŒ์ฟผ๋ฆฌ(Subquery)

ํ˜ธ๋นตยท2024๋…„ 7์›” 25์ผ

SQL_์ด๋ก 

๋ชฉ๋ก ๋ณด๊ธฐ
4/5

๐Ÿ“… ๊ณต๋ถ€ ๊ธฐ๊ฐ„ : 07. 25(๋ชฉ)

โญ๏ธ ๋‹จ์ผํ–‰ ์„œ๋ธŒ์ฟผ๋ฆฌ

  • ์„œ๋ธŒ์ฟผ๋ฆฌ๋ฌธ์˜ ๊ฐ’์ด ํ•˜๋‚˜์—ฌ์•ผ ํ•จ
-- [์—ฐ์Šต] ์‚ฌ์›๋ฒˆํ˜ธ๊ฐ€ 162๋ฒˆ์ธ ์‚ฌ์›์˜ ๊ธ‰์—ฌ์™€ ๊ฐ™์€ ๊ธ‰์—ฌ๋ฅผ ๋ฐ›๋Š” ์ง์›์˜ ์ด๋ฆ„, ๊ธ‰์—ฌ, ๋ถ€์„œ๋ฒˆํ˜ธ
-- 1) ์ฐพ์€ ๊ฐ’ : 10,500
SELECT salary
FROM hr.employees e 
WHERE employee_id = 162;

-- 2) ์ฐพ์€ ๊ฐ’์„ ๊ฐ€์ง€๊ณ  ๋‹ค์‹œ ์กฐํšŒ
SELECT first_name, salary, department_id 
FROM hr.employees e 
WHERE salary = 10500;

-- 3) ๋‹จ์ผํ–‰ ์„œ๋ธŒ์ฟผ๋ฆฌ๋กœ ํ•ฉ์น˜๊ธฐ
SELECT first_name, salary, department_id 
FROM hr.employees e 
WHERE salary = (SELECT salary
				FROM hr.employees e 
				WHERE employee_id = 162);

โญ๏ธ ๋ณต์ˆ˜ํ–‰(๋‹ค์ค‘ํ–‰) ์„œ๋ธŒ์ฟผ๋ฆฌ

  • ์„œ๋ธŒ์ฟผ๋ฆฌ๋ฌธ์˜ ๊ฐ’์ด ์—ฌ๋Ÿฌ ๊ฐœ
  • = ์—ฐ์‚ฐ์ž ๋Œ€์‹  IN ์—ฐ์‚ฐ์ž & ANY ์—ฐ์‚ฐ์ž & ALL ์—ฐ์‚ฐ์ž๋กœ ๋น„๊ต

1. IN ์—ฐ์‚ฐ์ž

/* [์—ฐ์Šต] 30๋ฒˆ ๋ถ€์„œ์˜ ์ง๊ธ‰๋“ค๊ณผ ๋™์ผํ•œ ์ง๊ธ‰์ด
๋‹ค๋ฅธ ํŒ€์—๋„ ์žˆ๋Š”์ง€ ์กฐ์‚ฌํ•˜๋Š” ์„œ๋ธŒ์ฟผ๋ฆฌ๋ฅผ ์ž‘์„ฑํ•˜์‹œ์˜ค	*/
SELECT * FROM hr.employees e 
WHERE job_id IN (SELECT DISTINCT job_id
				 FROM hr.employees e 
				 WHERE department_id = 30);

2. ANY ์—ฐ์‚ฐ์ž

  • ์ „์ฒด ๋ฐ์ดํ„ฐ ์ค‘ ๊ฐ€์žฅ ํฐ ๊ฐ’๋ณด๋‹ค ์ž‘์€ ๊ฐ’ โ†’ < any
  • ์ „์ฒด ๋ฐ์ดํ„ฐ ์ค‘ ๊ฐ€์žฅ ์ž‘์€ ๊ฐ’๋ณด๋‹ค ํฐ ๊ฐ’ โ†’ > any
  • ์ „์ฒด ๋ฐ์ดํ„ฐ ์ค‘ ํ•œ ๊ฐ’๊ณผ ๊ฐ™์€ ๊ฐ’ โ†’ = any
-- [์—ฐ์Šต] hr๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์กด์žฌํ•˜๋Š” employees ํ…Œ์ด๋ธ”์— 'ST_MAN'์ด๋ผ๋Š” ์ง๊ตฐ์ด ์žˆ๋‹ค.
-- 'ST_MAN'์ด๋ผ๋Š” ์ง๊ตฐ์ด ๋ฐ›๋Š” ๊ธ‰์—ฌ๋ณด๋‹ค ์ ์€ ๊ธ‰์—ฌ๋ฅผ ๋ฐ›๋Š” ์ง์›์˜ ์ •๋ณด๋ฅผ ์กฐํšŒ
			
-- ์ „์ฒด ๋ฐ์ดํ„ฐ ์ค‘ ๊ฐ€์žฅ ํฐ ๊ฐ’๋ณด๋‹ค ์ž‘์€ ๊ฐ’
SELECT salary
FROM hr.employees e 
WHERE job_id = 'ST_MAN'
ORDER BY 1;
-- [์ •๋‹ต]
SELECT first_name, salary
FROM hr.employees e
WHERE salary > ANY (SELECT salary
					FROM hr.employees e 
					WHERE job_id = 'ST_MAN'
					ORDER BY 1
					)
ORDER BY 2;

/* [์—ฐ์Šต2] job_title์ด 'Manager'์ธ ์ง์›๊ณผ ๋™์ผํ•œ ๊ธ‰์—ฌ๋ฅผ ๋ฐ›๋Š” ์ง์›์˜
์‚ฌ๋ฒˆ, ์ด๋ฆ„, job_id, ๊ธ‰์—ฌ์˜ ์ •๋ณด๋ฅผ ๊ธ‰์—ฌ์ˆœ์œผ๋กœ ์กฐํšŒํ•˜์‹œ์˜ค */
-- [์ •๋‹ต]
SELECT employee_id, first_name, job_id, salary
FROM hr.employees e
WHERE salary = ANY (SELECT salary
					FROM hr.employees e INNER JOIN hr.jobs j
					USING (job_id)
					WHERE job_title LIKE '%Manager')
ORDER BY 4;

3. ALL ์—ฐ์‚ฐ์ž

  • ์ „์ฒด ๋ฐ์ดํ„ฐ์—์„œ ์ œ์ผ ์ž‘์€ ๊ฐ’๋ณด๋‹ค ์ž‘์€ ๊ฐ’ โ†’ < all
  • ์ „์ฒด ๋ฐ์ดํ„ฐ์—์„œ ์ œ์ผ ํฐ ๊ฐ’๋ณด๋‹ค ํฐ ๊ฐ’ โ†’ > all
SELECT first_name, salary
FROM hr.employees e
WHERE salary < ALL (SELECT salary
					FROM hr.employees e 
					WHERE job_id = 'ST_MAN'
					ORDER BY salary
					)
ORDER BY 2;

๋‹ค์ค‘ ์ปฌ๋Ÿผ ์„œ๋ธŒ์ฟผ๋ฆฌ

  • ์„œ๋ธŒ์ฟผ๋ฆฌ๋ฌธ์ด ๋ฑ‰๋Š” ์ปฌ๋Ÿผ์ด ์—ฌ๋Ÿฌ ๊ฐœ
-- [์—ฐ์Šต] ๊ฐ ๋ถ€์„œ๋ณ„ ์ตœ๊ณ  ๊ธˆ์•ก์„ ์ˆ˜๋ นํ•˜๋Š” ์ง์›์˜ ์ •๋ณด(์‚ฌ์›๋ฒˆํ˜ธ, ์ด๋ฆ„, ๊ธ‰์—ฌ, ๋ถ€์„œ๋ช…, ์ง๊ธ‰๋ช…)
-- ์ปฌ๋Ÿผ์ด 2๊ฐœ ์กฐํšŒ๋จ
SELECT department_id, max(salary), min(salary) -- ๊ทธ๋ฃนํ•‘ํ•  ์ˆ˜ ์žˆ๋Š” ์ •๋ณด๋“ค๋งŒ select์ ˆ์— ์˜ฌ ์ˆ˜ ์žˆ์Œ
FROM hr.employees e
GROUP BY department_id;

-- ์„œ๋ธŒ์ฟผ๋ฆฌ ์‚ฌ์šฉํ•˜๊ธฐ
SELECT e.employee_id, e.first_name, e.salary, d.department_name, j.job_title
FROM hr.employees e
INNER JOIN hr.departments d 
on e.department_id = d.department_id
INNER JOIN hr.jobs j
ON  e.job_id = j.job_id
WHERE (e.department_id, e.salary) IN(SELECT department_id, max(salary)
								FROM hr.employees e
								GROUP BY department_id
								); 

Scalar ์„œ๋ธŒ์ฟผ๋ฆฌ

  • SELECT์ ˆ ์˜ ์ปฌ๋Ÿผ ์œ„์น˜์— ์‚ฌ์šฉ๋˜๋Š” ์„œ๋ธŒ์ฟผ๋ฆฌ

    ์„ฑ๋Šฅ ๋ฌธ์ œ ๋•Œ๋ฌธ์— Scalar ์„œ๋ธŒ์ฟผ๋ฆฌ๋ณด๋‹ค JOIN์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Œ

SELECT
	(SELECT last_name FROM hr.employees e2 WHERE first_name='Bruce') AS "Bruce์˜ ์„ฑ",
	(SELECT last_name FROM hr.employees e2 WHERE first_name='Daniel') AS "Daniel์˜ ์„ฑ"
FROM hr.employees e 
WHERE first_name = 'David';

์ƒํ˜ธ์—ฐ๊ด€ ์„œ๋ธŒ์ฟผ๋ฆฌ

์ƒํ˜ธ์—ฐ๊ด€ ์„œ๋ธŒ์ฟผ๋ฆฌ์—์„œ ๋˜‘๊ฐ™์€ ์ ˆ์ฐจ๋ฅผ ๊ณ„์† ๋ฐ˜๋ณตํ•˜๋Š” ๊ฒƒ์€ ๋น„ํšจ์œจ์  => Inline View๋ฅผ ์‚ฌ์šฉ

-- [์—ฐ์Šต] ๊ฐ ๋ถ€์„œ๋ณ„๋กœ ํ•ด๋‹น ๋ถ€์„œ์˜ ๊ธ‰์—ฌ ํ‰๊ท  ๋ฏธ๋งŒ์˜ ๊ธ‰์—ฌ๋ฅผ ์ˆ˜๋ นํ•˜๋Š” ์ง์› ๋ช…๋‹จ ์กฐํšŒ
-- (๋ถ€์„œ๋ฒˆํ˜ธ, ์‚ฌ์›๋ฒˆํ˜ธ, ์ด๋ฆ„, ๊ธ‰์—ฌ, ๋ถ€์„œ๋ณ„ ํ‰๊ท ๊ธ‰์—ฌ)
SELECT department_id, employee_id, first_name, salary
FROM hr.employees e
WHERE salary <
			(SELECT avg(salary)
			FROM hr.employees e 
			WHERE department_id = e.department_id);
ORDER BY 1,2;

โญ๏ธ Inline View

๋งŽ์ด ์‚ฌ์šฉ๋จ

  • ์„œ๋ธŒ์ฟผ๋ฆฌ๊ฐ€ From์ ˆ์— ๊ธฐ์ˆ 
  • ์„œ๋ธŒ์ฟผ๋ฆฌ๋กœ ์กฐํšŒ๋˜๋Š” ๊ฒฐ๊ณผ๋ฅผ ํ…Œ์ด๋ธ”๋กœ ์‚ฌ์šฉํ•จ
  • ์„œ๋ธŒ์ฟผ๋ฆฌ์—์„œ ์กฐํšŒ๋˜๋Š” ์ปฌ๋Ÿผ์—๋Š” ๋ณ„์นญ์„ ์‚ฌ์šฉํ•ด์•ผ ํ•จ
-- ์ƒํ˜ธ์—ฐ๊ด€ ์„œ๋ธŒ์ฟผ๋ฆฌ ์ฝ”๋“œ๋ฅผ ์ธ๋ผ์ธ๋ทฐ๋กœ ์ˆ˜์ •
SELECT e.department_id, e.employee_id, e.first_name, e.salary, round(๊ธ‰์—ฌํ‰๊ท )
FROM (SELECT department_id "๋ถ€์„œ๋ฒˆํ˜ธ", avg(salary) AS "๊ธ‰์—ฌํ‰๊ท "
	  FROM hr.employees e 
	  GROUP BY department_id) tbl, hr.employees e -- INNER JOINํ•œ ๊ฒƒ 
WHERE tbl.๋ถ€์„œ๋ฒˆํ˜ธ = e.department_id
AND e.salary < tbl.๊ธ‰์—ฌํ‰๊ท 
ORDER BY 1,2;

profile
์ธ๋ฅ˜์˜ ์œ„๋Œ€ํ•œ ๋Œ€ํ™”์— ์ฐธ์—ฌํ•˜๊ธฐ ์œ„ํ•ด ๋‹ค์–‘ํ•œ ์–ธ์–ด๋ฅผ ํƒ๊ตฌํ•ฉ๋‹ˆ๋‹ค.

0๊ฐœ์˜ ๋Œ“๊ธ€