๐Ÿ“ŒSQL ๋ฌธ๋ฒ• - GROUP BY & HAVING ๊ตฌ๋ถ„ํ•˜๊ธฐ

SQL์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์ง‘๊ณ„ํ•  ๋•Œ ๊ผญ ๋“ฑ์žฅํ•˜๋Š” ๋‘ ์นœ๊ตฌ, GROUP BY ์™€ HAVING. ์ด ๋‘˜์€ ํ•จ๊ป˜ ์“ฐ์ด์ง€๋งŒ, ์—ญํ• ์ด ์™„์ „ํžˆ ๋‹ค๋ฆ…๋‹ˆ๋‹ค.์ด๋ฒˆ ๊ธ€์—์„œ๋Š” ๋‘ ๋ฌธ๋ฒ•์„ ์•Œ์•„๋ด…์‹œ๋‹ค.
avatar
2025.04.07
ยท
7 min read

SQL์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์ง‘๊ณ„ํ•  ๋•Œ ๊ผญ ๋“ฑ์žฅํ•˜๋Š” ๋‘ ์นœ๊ตฌ,
GROUP BY ์™€ HAVING.

์ด ๋‘˜์€ ํ•จ๊ป˜ ์“ฐ์ด์ง€๋งŒ, ์—ญํ• ์ด ์™„์ „ํžˆ ๋‹ค๋ฆ…๋‹ˆ๋‹ค.
์ด๋ฒˆ ๊ธ€์—์„œ๋Š” ๋‘ ๋ฌธ๋ฒ•์„ ์™„๋ฒฝํ•˜๊ฒŒ ๊ตฌ๋ถ„ํ•˜๊ณ , ์ œ๋Œ€๋กœ ํ™œ์šฉํ•˜๋Š” ๋ฒ•์„ ์ตํ˜€๋ด…๋‹ˆ๋‹ค!


โœ… GROUP BY๋ž€?

GROUP BY๋Š” ํŠน์ • ์ปฌ๋Ÿผ ๊ฐ’์„ ๊ธฐ์ค€์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๊ทธ๋ฃนํ™”ํ•ด์„œ
๊ทธ๋ฃน๋ณ„๋กœ ์ง‘๊ณ„ ํ•จ์ˆ˜(SUM, COUNT ๋“ฑ)๋ฅผ ์ ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ์ ˆ์ž…๋‹ˆ๋‹ค.

SELECT ์ปฌ๋Ÿผ๋ช…, ์ง‘๊ณ„ํ•จ์ˆ˜
FROM ํ…Œ์ด๋ธ”๋ช…
GROUP BY ๊ธฐ์ค€์ปฌ๋Ÿผ;

๐Ÿ”น ์˜ˆ์‹œ

๊ฐ™์€ custid ๊ฐ’์„ ๊ฐ€์ง„ ํ–‰๋ผ๋ฆฌ ๋ฌถ์–ด์„œ

๊ฐ ๊ทธ๋ฃน์— ๋Œ€ํ•ด SUM(saleprice) ๊ณ„์‚ฐ

-- ๊ณ ๊ฐ๋ณ„ ์ด ๊ตฌ๋งค ๊ธˆ์•ก
SELECT custid, SUM(saleprice)
FROM Orders
GROUP BY custid;

โœ… HAVING์ด๋ž€?

HAVING์€ GROUP BY๋กœ ๊ทธ๋ฃนํ™”๋œ ๊ฒฐ๊ณผ์— ์กฐ๊ฑด์„ ๊ฑธ ๋•Œ ์‚ฌ์šฉํ•˜๋Š” ์ ˆ์ž…๋‹ˆ๋‹ค.
์ฆ‰, ๊ทธ๋ฃน ๋‹จ์œ„์˜ ํ•„ํ„ฐ๋ง์„ ๋‹ด๋‹นํ•ฉ๋‹ˆ๋‹ค.

SELECT ์ปฌ๋Ÿผ๋ช…, ์ง‘๊ณ„ํ•จ์ˆ˜
FROM ํ…Œ์ด๋ธ”๋ช…
GROUP BY ๊ธฐ์ค€์ปฌ๋Ÿผ
HAVING ์กฐ๊ฑด;

๐Ÿ”น ์˜ˆ์‹œ

WHERE COUNT(*) >= 2๋Š” โŒ ๋ถˆ๊ฐ€๋Šฅ
HAVING์€ ์ง‘๊ณ„ ํ•จ์ˆ˜์™€ ํ•จ๊ป˜ ์กฐ๊ฑด ์ง€์ • ๊ฐ€๋Šฅ
-- 2ํšŒ ์ด์ƒ ์ฃผ๋ฌธํ•œ ๊ณ ๊ฐ๋งŒ ์กฐํšŒ
SELECT custid, COUNT(*)
FROM Orders
GROUP BY custid
HAVING COUNT(*) >= 2;

๐Ÿง  WHERE vs HAVING ์ฐจ์ด

ํ•ญ๋ชฉ

WHERE ์ ˆ

HAVING ์ ˆ

์ ์šฉ ์‹œ์ 

GROUP BY ์ด์ „

GROUP BY ์ดํ›„

๋Œ€์ƒ

๊ฐœ๋ณ„ ํ–‰(Row)

๊ทธ๋ฃน(Group)

์ง‘๊ณ„ ํ•จ์ˆ˜ ์‚ฌ์šฉ

โŒ ์‚ฌ์šฉ ๋ถˆ๊ฐ€

โœ… ์‚ฌ์šฉ ๊ฐ€๋Šฅ

์ฃผ์šฉ๋„

๊ฐœ๋ณ„ ๋ฐ์ดํ„ฐ ํ•„ํ„ฐ๋ง

๊ทธ๋ฃนํ•‘๋œ ๊ฒฐ๊ณผ ํ•„ํ„ฐ๋ง

์‚ฌ์šฉ ์œ„์น˜

SELECT ~ FROM ~ WHERE

SELECT ~ FROM ~ GROUP BY ~ HAVING


๐Ÿงช ์‹ค์ „ ์˜ˆ์ œ ๋น„๊ต

-- ์ถœํŒ์‚ฌ๋ณ„ ๋„์„œ ํ‰๊ท  ๊ฐ€๊ฒฉ ๊ตฌํ•˜๊ธฐ
SELECT publisher, AVG(price) AS avg_price
FROM Book
GROUP BY publisher;

-- ํ‰๊ท  ๊ฐ€๊ฒฉ์ด 15,000์› ์ด์ƒ์ธ ์ถœํŒ์‚ฌ๋งŒ
SELECT publisher, AVG(price)
FROM Book
GROUP BY publisher
HAVING AVG(price) >= 15000;

-- ๊ณ ๊ฐ ์ด๋ฆ„ + ์ด ๊ตฌ๋งค ๊ธˆ์•ก ์ถœ๋ ฅ
SELECT name, SUM(saleprice)
FROM Customer C, Orders O
WHERE C.custid = O.custid
GROUP BY name;

โš  ์ž์ฃผ ํ•˜๋Š” ์‹ค์ˆ˜

โ— WHERE ์ ˆ์— ์ง‘๊ณ„ ํ•จ์ˆ˜๋ฅผ ์“ฐ๋ฉด ์˜ค๋ฅ˜ ๋ฐœ์ƒ
โ— GROUP BY์— ํฌํ•จ๋˜์ง€ ์•Š์€ ์ปฌ๋Ÿผ์„ SELECT์—์„œ ์‚ฌ์šฉํ•˜๋ฉด ์˜ค๋ฅ˜ ๋ฐœ์ƒ

-- ์˜ˆ: ์˜ค๋ฅ˜ ๋ฐœ์ƒ
SELECT publisher, price
FROM Book
GROUP BY publisher; -- price๋Š” ๊ทธ๋ฃน ๊ธฐ์ค€์ด ์•„๋‹˜

โ†’ ์ด๋Ÿด ๊ฒฝ์šฐ MAX(price) ๋˜๋Š” AVG(price)์ฒ˜๋Ÿผ ์ง‘๊ณ„ ํ•จ์ˆ˜๋กœ ๊ฐ์‹ธ์ค˜์•ผ ํ•จ


๐Ÿ“ฆ ์‘์šฉ ์˜ˆ์ œ ๋ชจ์Œ

-- ์ถœํŒ์‚ฌ๋ณ„ ๋„์„œ ํ‰๊ท  ๊ฐ€๊ฒฉ์ด 15,000 ์ด์ƒ์ธ ๊ฒฝ์šฐ๋งŒ
SELECT publisher, AVG(price) AS avg_price
FROM Book
GROUP BY publisher
HAVING AVG(price) >= 15000;

-- ๊ณ ๊ฐ๋ณ„ ์ด๊ตฌ๋งค๊ธˆ์•ก์ด 5๋งŒ ์› ์ด์ƒ
SELECT custid, SUM(saleprice)
FROM Orders
GROUP BY custid
HAVING SUM(saleprice) >= 50000;

๐Ÿ“Œ ๋งˆ๋ฌด๋ฆฌ

ํ•ญ๋ชฉ

์„ค๋ช…

GROUP BY

ํŠน์ • ์ปฌ๋Ÿผ ๊ธฐ์ค€์œผ๋กœ ํ–‰๋“ค์„ ๊ทธ๋ฃนํ•‘ํ•จ

์ง‘๊ณ„ ํ•จ์ˆ˜ ์‚ฌ์šฉ

SUM(), AVG(), COUNT() ๋“ฑ ๊ทธ๋ฃน๋ณ„ ์š”์•ฝ ๊ณ„์‚ฐ ๊ฐ€๋Šฅ

HAVING

๊ทธ๋ฃนํ•‘ ๊ฒฐ๊ณผ์— ์กฐ๊ฑด์„ ์ถ”๊ฐ€ํ•จ (์ง‘๊ณ„ ํ•จ์ˆ˜์™€ ํ•จ๊ป˜ ์‚ฌ์šฉ)

WHERE์™€์˜ ์ฐจ์ด

WHERE๋Š” ํ–‰ ํ•„ํ„ฐ๋ง, HAVING์€ ๊ทธ๋ฃน ํ•„ํ„ฐ๋ง (์ง‘๊ณ„ ํ•จ์ˆ˜ ์‚ฌ์šฉ ์—ฌ๋ถ€์— ์ฃผ์˜)

์ฃผ์˜์‚ฌํ•ญ

SELECT์— ๋‚˜์˜ค๋Š” ์ปฌ๋Ÿผ์€ ๋Œ€๋ถ€๋ถ„ GROUP BY์—๋„ ํฌํ•จ๋˜์–ด์•ผ ํ•จ

๐Ÿ“˜ ํ•™์Šต ํŒ
โ€ข GROUP BY ์—†์ด HAVING๋งŒ ์“ฐ๋Š” ๊ฑด โŒ (ํ•ญ์ƒ ์ง๊ฟ!)
โ€ข SELECT์— ๋‚˜์˜ค๋Š” ์ปฌ๋Ÿผ์€ ๋Œ€๋ถ€๋ถ„ GROUP BY์—๋„ ์žˆ์–ด์•ผ ์•ˆ์ „
โ€ข HAVING์€ ํ•ญ์ƒ ์ง‘๊ณ„ ๊ฒฐ๊ณผ๋ฅผ ํ•„ํ„ฐ๋งํ•œ๋‹ค๋Š” ์ ์„ ๊ธฐ์–ตํ•˜์ž







- ์ปฌ๋ ‰์…˜ ์•„ํ‹ฐํด