Database/SQL ๊ธฐ์ดˆ

SQL ๊ธฐ์ดˆ - GROUP BY - HAVING

UNarD 2026. 3. 19. 16:50

๐Ÿ—‚๏ธ SQL GROUP BY, HAVING

SELECT๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์กฐํšŒํ•˜๋‹ค ๋ณด๋ฉด ๊ทธ๋ฃน์œผ๋กœ ๋ฌถ๊ฑฐ๋‚˜ ์กฐ๊ฑด์„ ๊ฑธ๊ณ  ์‹ถ์„ ๋•Œ๊ฐ€ ์ƒ๊น๋‹ˆ๋‹ค.
์˜ค๋Š˜์€ ๊ทธ๋Ÿด ๋•Œ ์“ฐ๋Š” ๋‘ ๊ฐ€์ง€ ์ ˆ์„ ์ •๋ฆฌํ•ด ๋ดค์Šต๋‹ˆ๋‹ค ๐Ÿ˜Š

๐Ÿ—’๏ธ ์˜ˆ์‹œ ํ…Œ์ด๋ธ” โ€” students

id name grade score teacher_id
1 ๊น€์ฒ ์ˆ˜ 1 85 1
2 ์ด์˜ํฌ 2 NULL 1
3 ๋ฐ•๋ฏผ์ค€ 1 90 2
4 ์ตœ์ง€์› 3 72 NULL
5 ์ •์ˆ˜ํ˜„ 2 NULL 2
6 ํ•œ์ง€๋ฏผ 1 78 1
7 ์œค์„œ์ค€ 3 95 2
8 ๊ฐ•๋‹ค์€ 2 88 1
9 ์ž„ํ˜„์šฐ 3 NULL 2
10 ์˜ค์ง€์•„ 1 65 NULL
CREATE DATABASE IF NOT EXISTS practice;
USE practice;

DROP TABLE IF EXISTS students;

CREATE TABLE students (
    id         INT,
    name       VARCHAR(10),
    grade      INT,
    score      INT,
    teacher_id INT
);

INSERT INTO students VALUES (1,  '๊น€์ฒ ์ˆ˜', 1, 85,   1);
INSERT INTO students VALUES (2,  '์ด์˜ํฌ', 2, NULL,  1);
INSERT INTO students VALUES (3,  '๋ฐ•๋ฏผ์ค€', 1, 90,   2);
INSERT INTO students VALUES (4,  '์ตœ์ง€์›', 3, 72,   NULL);
INSERT INTO students VALUES (5,  '์ •์ˆ˜ํ˜„', 2, NULL,  2);
INSERT INTO students VALUES (6,  'ํ•œ์ง€๋ฏผ', 1, 78,   1);
INSERT INTO students VALUES (7,  '์œค์„œ์ค€', 3, 95,   2);
INSERT INTO students VALUES (8,  '๊ฐ•๋‹ค์€', 2, 88,   1);
INSERT INTO students VALUES (9,  '์ž„ํ˜„์šฐ', 3, NULL,  2);
INSERT INTO students VALUES (10, '์˜ค์ง€์•„', 1, 65,   NULL);

โ€ผ๏ธ ์œ„ ํ…Œ์ด๋ธ”์„ ๊ธฐ์ค€์œผ๋กœ ์•„๋ž˜ ๋ฌธ๋ฒ• ์‚ฌ์šฉ๋ฒ•์„ ์„ค๋ช…ํ• ๊ฒŒ์š”.


๐Ÿ—ƒ๏ธ GROUP BY โ€” ๊ทธ๋ฃน์œผ๋กœ ๋ฌถ๊ธฐ

๊ฐ™์€ ๊ฐ’์„ ๊ฐ€์ง„ ํ–‰๋“ค์„ ํ•˜๋‚˜์˜ ๊ทธ๋ฃน์œผ๋กœ ๋ฌถ๋Š” ์ ˆ์ž…๋‹ˆ๋‹ค.
์ง‘๊ณ„ ํ•จ์ˆ˜(COUNT, SUM, AVG ๋“ฑ)์™€ ํ•จ๊ป˜ ์จ์•ผ ์˜๋ฏธ๊ฐ€ ์žˆ์–ด์š”. ๐Ÿ‘‰ ๐Ÿ”— ์ง‘๊ณ„ ํ•จ์ˆ˜ ๋ณด๋Ÿฌ๊ฐ€๊ธฐ

๐ŸŽ€ ๊ธฐ๋ณธ ๋ฌธ๋ฒ•

SELECT ์ปฌ๋Ÿผ๋ช… FROM ํ…Œ์ด๋ธ”๋ช…
GROUP BY ์ปฌ๋Ÿผ๋ช…;

๐Ÿ”น ํ•™๋…„๋ณ„ ํ•™์ƒ ์ˆ˜

SELECT grade, COUNT(*) AS ํ•™์ƒ์ˆ˜
FROM students
GROUP BY grade;
๐Ÿ“ฅ ๊ฒฐ๊ณผ
grade ํ•™์ƒ์ˆ˜
1 4
2 3
3 3

๐Ÿ”น ํ•™๋…„๋ณ„ ํ‰๊ท  ์ ์ˆ˜

SELECT grade, AVG(score) AS ํ‰๊ท ์ ์ˆ˜
FROM students
GROUP BY grade;
๐Ÿ“ฅ ๊ฒฐ๊ณผ
grade ํ‰๊ท ์ ์ˆ˜
1 79.5000
2 88.0000
3 83.5000

NULL์€ ์ง‘๊ณ„ ํ•จ์ˆ˜์—์„œ ๋ฌด์‹œ๋˜๋ฏ€๋กœ ๊ฐ ํ•™๋…„์˜ ์‹ค์ œ ์‘์‹œ์ž ๊ธฐ์ค€์œผ๋กœ ํ‰๊ท ์ด ๊ณ„์‚ฐ๋ฉ๋‹ˆ๋‹ค.

โš ๏ธ GROUP BY ์‚ฌ์šฉ ์‹œ ์ฃผ์˜์‚ฌํ•ญ

SELECT์— ์“ฐ๋Š” ์ปฌ๋Ÿผ์€ ๋ฐ˜๋“œ์‹œ GROUP BY์— ํฌํ•จ๋˜๊ฑฐ๋‚˜ ์ง‘๊ณ„ ํ•จ์ˆ˜๋กœ ๊ฐ์‹ธ์•ผ ํ•ฉ๋‹ˆ๋‹ค.
๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

โŒ ์˜ค๋ฅ˜
SELECT grade, name, COUNT(*)
FROM students
GROUP BY grade;
โœ… ์ •์ƒ
SELECT grade, COUNT(*)
FROM students
GROUP BY grade;

๐Ÿ”Ž HAVING โ€” ๊ทธ๋ฃน์— ์กฐ๊ฑด ๊ฑธ๊ธฐ

GROUP BY๋กœ ๋ฌถ์ธ ๊ฒฐ๊ณผ์— ์กฐ๊ฑด์„ ๊ฑฐ๋Š” ์ ˆ์ž…๋‹ˆ๋‹ค.
WHERE๊ฐ€ ํ–‰์„ ํ•„ํ„ฐ๋งํ•œ๋‹ค๋ฉด, HAVING์€ ๊ทธ๋ฃน์„ ํ•„ํ„ฐ๋งํ•ฉ๋‹ˆ๋‹ค.

๐ŸŽ€ ๊ธฐ๋ณธ ๋ฌธ๋ฒ•

SELECT ์ปฌ๋Ÿผ๋ช… FROM ํ…Œ์ด๋ธ”๋ช…
GROUP BY ์ปฌ๋Ÿผ๋ช…
HAVING ์กฐ๊ฑด;

๐Ÿ”น ํ•™์ƒ์ด 4๋ช… ์ด์ƒ์ธ ํ•™๋…„๋งŒ

SELECT grade, COUNT(*) AS ํ•™์ƒ์ˆ˜
FROM students
GROUP BY grade
HAVING COUNT(*) >= 4;
๐Ÿ“ฅ ๊ฒฐ๊ณผ
grade ํ•™์ƒ์ˆ˜
1 4
โš ๏ธ WHERE vs HAVING

์ง‘๊ณ„ ํ•จ์ˆ˜์— ์กฐ๊ฑด์„ ๊ฑธ ๋•Œ๋Š” ๋ฐ˜๋“œ์‹œ HAVING์„ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
WHERE์—๋Š” ์ง‘๊ณ„ ํ•จ์ˆ˜๋ฅผ ์“ธ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

โŒ ์˜ค๋ฅ˜
WHERE COUNT(*) >= 4
โœ… ์ •์ƒ
HAVING COUNT(*) >= 4

๐Ÿ” ์ ˆ ์‹คํ–‰ ์ˆœ์„œ

FROM โ†’ WHERE โ†’ GROUP BY โ†’ HAVING โ†’ SELECT โ†’ ORDER BY

โœ… ์ „์ฒด ์ ˆ์„ ํ•จ๊ป˜ ์“ฐ๋Š” ์˜ˆ์‹œ

SELECT grade, COUNT(*) AS ํ•™์ƒ์ˆ˜, AVG(score) AS ํ‰๊ท ์ ์ˆ˜
FROM students
WHERE score IS NOT NULL          -- NULL ์ œ์™ธ
GROUP BY grade                   -- ํ•™๋…„๋ณ„ ๊ทธ๋ฃนํ™”
HAVING AVG(score) >= 70          -- ํ‰๊ท  70์  ์ด์ƒ์ธ ํ•™๋…„๋งŒ
ORDER BY ํ‰๊ท ์ ์ˆ˜ DESC;           -- ํ‰๊ท ์ ์ˆ˜ ๋‚ด๋ฆผ์ฐจ์ˆœ ์ •๋ ฌ
๐Ÿ“ฅ ๊ฒฐ๊ณผ
grade ํ•™์ƒ์ˆ˜ ํ‰๊ท ์ ์ˆ˜
2 1 88.0000
3 2 83.5000
1 4 79.5000

โ˜• ๋งˆ๋ฌด๋ฆฌ

์ ˆ ์—ญํ•  ์œ„์น˜
GROUP BY ๊ฐ™์€ ๊ฐ’์˜ ํ–‰์„ ๊ทธ๋ฃน์œผ๋กœ ๋ฌถ๊ธฐ WHERE ๋’ค
HAVING ๊ทธ๋ฃน์— ์กฐ๊ฑด ๊ฑธ๊ธฐ GROUP BY ๋’ค

๐Ÿ“š ์ฐธ๊ณ ์ž๋ฃŒ