๐SQL ๋ฌธ๋ฒ - ์๋ธ์ฟผ๋ฆฌ(Subquery)

์๋ธ์ฟผ๋ฆฌ๋ SQL ์ฟผ๋ฆฌ ์์ ๋ ๋ค๋ฅธ ์ฟผ๋ฆฌ๊ฐ ๋ค์ด์๋ ํํ๋ฅผ ๋งํฉ๋๋ค.
'์ฟผ๋ฆฌ ์์ ์ฟผ๋ฆฌ'๋ก, ๋ณต์กํ ์กฐ๊ฑด์ด๋ ๊ณ์ฐ์ ๊น๋ํ๊ฒ ์ฒ๋ฆฌํ ์ ์์ต๋๋ค.
โ ์๋ธ์ฟผ๋ฆฌ๋?
์๋ธ์ฟผ๋ฆฌ(Subquery) ๋
๋ค๋ฅธ SQL ๋ฌธ์ฅ ์์์ ์ฌ์ฉ๋๋ ํ์ SELECT ๋ฌธ์ ๋งํฉ๋๋ค.
๋ณดํต WHERE
, FROM
, SELECT
์ ์์์ ์ฌ์ฉ๋๊ณ ,
ํ๋์ ๊ฐ์ ๋ฐํํ๊ฑฐ๋, ์ฌ๋ฌ ํ/์ด์ ๋ฐํํ ์๋ ์์ด์.
๐น ์๋ธ์ฟผ๋ฆฌ์ ์์น
์์น | ์์ ์ค๋ช |
| ์กฐ๊ฑด์ ์ ํ ๋ ์ฌ์ฉํ๋ ์๋ธ์ฟผ๋ฆฌ |
| ํ ์ด๋ธ์ฒ๋ผ ์๋ธ์ฟผ๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ ์ฌ์ฉ |
| ํน์ ์ด์ ๊ฐ์ ์๋ธ์ฟผ๋ฆฌ๋ก ๊ณ์ฐ |
์์ ๊ณตํต ํ ์ด๋ธ ์ค์

๐ธ ๋จ์ผ ํ ์๋ธ์ฟผ๋ฆฌ (์ค์นผ๋ผ ์๋ธ์ฟผ๋ฆฌ)
ํ๋์ ๊ฐ(์ค์นผ๋ผ ๊ฐ)์ ๋ฐํํ๋ ์๋ธ์ฟผ๋ฆฌ
SELECT name
FROM Customer
WHERE custid = (
SELECT custid
FROM Orders
WHERE saleprice = 30000
);
๐ ํด์
โข ์๋ธ์ฟผ๋ฆฌ: saleprice๊ฐ 30000์ธ ์ฃผ๋ฌธ์ custid โ 2 ๋ฐํ
โข ๋ฉ์ธ์ฟผ๋ฆฌ: custid = 2์ธ ๊ณ ๊ฐ โ ์ด์ํฌ
๐ธ ๋ค์ค ํ ์๋ธ์ฟผ๋ฆฌ
์ฌ๋ฌ ํ์ ๋ฐํํ๋ ์๋ธ์ฟผ๋ฆฌ๋ก, IN, ANY, ALL ๋ฑ๊ณผ ํจ๊ป ์ฌ์ฉ
--IN
SELECT name
FROM Customer
WHERE custid IN (
SELECT custid
FROM Orders
WHERE saleprice >= 20000
);
๐ ํด์
๐น ์๋ธ์ฟผ๋ฆฌ: Orders ํ ์ด๋ธ์์ saleprice >= 20000 ์กฐ๊ฑด์ ๋ง์กฑํ๋ ๋ชจ๋ custid ๋ฐํ (โ 2)
๐น ๋ฉ์ธ์ฟผ๋ฆฌ: Customer ํ ์ด๋ธ์์ ํด๋น custid๋ฅผ ๊ฐ์ง name ์ถ์ถ (โ ์ด์ํฌ)
๐ธ ๋ค์ค ์ด ์๋ธ์ฟผ๋ฆฌ
๋ ๊ฐ ์ด์์ ์ปฌ๋ผ(์ด)์ ๋ฐํํ๋ ์๋ธ์ฟผ๋ฆฌ
SELECT *
FROM Orders
WHERE (custid, saleprice) IN (
SELECT custid, saleprice
FROM Orders
WHERE saleprice >= 20000
);
๐ ํด์
๐น ์๋ธ์ฟผ๋ฆฌ: Orders ํ ์ด๋ธ์์ saleprice >= 20000์ธ ํ์ custid, saleprice ํํ ๋ฐํ
๐น ๋ฉ์ธ์ฟผ๋ฆฌ: Orders ํ ์ด๋ธ์์ ํด๋น (custid, saleprice) ์์ด ์กด์ฌํ๋ ํ ์ถ๋ ฅ (โ 2,25000 ๋ฐ 2,30000 ํฌํจ)
๐ธ ์๊ด ์๋ธ์ฟผ๋ฆฌ (Correlated Subquery)
๋ฉ์ธ ์ฟผ๋ฆฌ์ ํ๋ง๋ค ์๋ธ์ฟผ๋ฆฌ๋ฅผ ๋ฐ๋ณต ์คํํ๋ ๊ตฌ์กฐ
SELECT name
FROM Customer C
WHERE EXISTS (
SELECT *
FROM Orders O
WHERE O.custid = C.custid AND O.saleprice > 20000
);
์๋ธ์ฟผ๋ฆฌ๊ฐ ๋ฐ๊นฅ ์ฟผ๋ฆฌ์ ๊ฐ์ ์ฐธ์กฐ
์ฑ๋ฅ์ ์ฃผ์, ํ์ํ ๋๋ง ์ฌ์ฉ!
๐ ํด์
โข ๊ณ ๊ฐ๋ง๋ค ์ฃผ๋ฌธ์ ์ฐพ์๋ณด๋ฉฐ 25000 ์ด์์ธ ์ฃผ๋ฌธ์ด ์กด์ฌํ๋ฉด TRUE
โข ์ด์ํฌ๋ ์กฐ๊ฑด์ ๋ง์กฑํ๋ ์ฃผ๋ฌธ์ด ์์ผ๋ฏ๋ก ์ถ๋ ฅ
โข ๊น์ฒ ์, ๋ฐ๋ฏผ์๋ ์ ์ธ๋จ
๐น ์๋ธ์ฟผ๋ฆฌ: Orders ํ ์ด๋ธ์ ํ์ํ๋ฉด์ ๋ฐ๊นฅ์ Customer์ custid์ ํด๋นํ๋ ์ฃผ๋ฌธ ์ค saleprice > 20000 ์กฐ๊ฑด์ ํ์ธ
๐น ๋ฉ์ธ์ฟผ๋ฆฌ: ์กฐ๊ฑด์ ๋ง์กฑํ๋ ์ฃผ๋ฌธ์ด ์กด์ฌํ๋ ๊ณ ๊ฐ์ name๋ง ์ถ๋ ฅ (โ ์ด์ํฌ)
๐ธ EXISTS ์๋ธ์ฟผ๋ฆฌ
์๋ธ์ฟผ๋ฆฌ ๊ฒฐ๊ณผ๊ฐ ์กด์ฌํ๋ฉด TRUE, ์๋๋ฉด FALSE
SELECT name
FROM Customer C
WHERE EXISTS (
SELECT *
FROM Orders O
WHERE O.custid = C.custid
);
๊ฒฐ๊ณผ์ ๋ด์ฉ์ด ์ค์ํ ๊ฒ ์๋๋ผ, ์กด์ฌ ์ฌ๋ถ๋ง ํ๋จ!
๐ ํด์
โข custid๊ฐ Orders์ ์กด์ฌํ๋ฉด ์ถ๋ ฅ
โข ์ฃผ๋ฌธ ๊ธฐ๋ก์ด ์๋ ๊ณ ๊ฐ: ๊น์ฒ ์(1), ์ด์ํฌ(2)
โข ์ฃผ๋ฌธ ์๋ ๋ฐ๋ฏผ์(3)๋ ์ ์ธ๋จ
๐ฆ ์ค์ ์์ ์ ๋ฆฌ
-- ์ต๊ณ ๊ฐ ๋์๋ฅผ ์ฃผ๋ฌธํ ๊ณ ๊ฐ ์ด๋ฆ
SELECT DISTINCT name
FROM Customer C, Orders O, Book B
WHERE C.custid = O.custid AND O.bookid = B.bookid
AND B.price = (SELECT MAX(price) FROM Book);
-- ์ฃผ๋ฌธ์ด ์๋ ๊ณ ๊ฐ ์ฐพ๊ธฐ
SELECT name
FROM Customer C
WHERE NOT EXISTS (
SELECT *
FROM Orders O
WHERE C.custid = O.custid
);
๐ง ๋ง๋ฌด๋ฆฌ
๊ตฌ๋ถ | ์ค๋ช | ์ฌ์ฉ ํค์๋ |
๋จ์ผ ํ ์๋ธ์ฟผ๋ฆฌ | ํ๋์ ๊ฐ ๋ฐํ, ์กฐ๊ฑด๋ฌธ๊ณผ ํจ๊ป ์ฌ์ฉ |
|
๋ค์ค ํ ์๋ธ์ฟผ๋ฆฌ | ์ฌ๋ฌ ํ ๋ฐํ, ๋ชฉ๋ก ๋น๊ต |
|
๋ค์ค ์ด ์๋ธ์ฟผ๋ฆฌ | ์ฌ๋ฌ ์ปฌ๋ผ์ ํํ ํํ๋ก ๋ฐํ |
|
์๊ด ์๋ธ์ฟผ๋ฆฌ | ๋ฐ๊นฅ ์ฟผ๋ฆฌ์ ๊ฐ์ ์ฐธ์กฐํ๋ฉฐ ํ๋ง๋ค ๋ฐ๋ณต ์คํ๋จ | ๋ฐ๊นฅ ์ฟผ๋ฆฌ์ ์ปฌ๋ผ ์ฌ์ฉ |
EXISTS ์๋ธ์ฟผ๋ฆฌ | ๊ฒฐ๊ณผ๊ฐ ์กด์ฌํ๋์ง๋ง ํ๋จ (TRUE/FALSE) |
|
๐ ํ์ต ํ
โข ์๋ธ์ฟผ๋ฆฌ๋ ๋ณต์กํ ์ฟผ๋ฆฌ๋ฅผ ๋ ์ฝ๊ธฐ ์ฝ๊ฒ ๋ง๋ค์ด์ค๋๋ค.
โข ๋จ์ผ ๊ฐ์ธ์ง, ์ฌ๋ฌ ํ์ธ์ง์ ๋ฐ๋ผ ์ ์ ํ ์ฐ์ฐ์๋ฅผ ์จ์ผ ํด์.
โข ์๊ด ์๋ธ์ฟผ๋ฆฌ๋ ๊ฐ๋ ์ฑ ์ข์ง๋ง ์ฑ๋ฅ ๋ถ๋ด์ด ์์ ์ ์์ด์.