์ง๊ณํจ์, HAVING



๐ก ๋ฐ์ดํฐ๋ฅผ ๊ทธ๋ฃน์ผ๋ก ๋ฌถ๊ณ ์์ฝํ๋ ํต์ฌ ๊ธฐ์ ์ ์ ๋ฆฌํ๋ค.
๋ฐ์ดํฐ๋ฅผ ํน์ ๊ธฐ์ค์ผ๋ก ๋ฌถ์ด์ ์ง๊ณํ๋ ๊ฒ.
์: "์ ์ ๋ณ ์ด ์ฃผ๋ฌธ ๊ธ์ก", "์๋ณ ๋งค์ถ", "์ํ๋ณ ํ๋งค ์๋"
โ ์ด๋ฐ ์ง๋ฌธ์ ๋ตํ๋ ค๋ฉด GROUP BY ํ์!
[orders]
| order_id | user_id | product | amount | order_date |
|----------|---------|---------|--------|------------|
| 1 | 101 | ๋
ธํธ๋ถ | 1500000 | 2024-01-15 |
| 2 | 101 | ๋ง์ฐ์ค | 50000 | 2024-01-20 |
| 3 | 102 | ํค๋ณด๋ | 100000 | 2024-01-25 |
| 4 | 102 | ๋ชจ๋ํฐ | 300000 | 2024-02-10 |
| 5 | 103 | ๋
ธํธ๋ถ | 1500000 | 2024-02-15 |
| 6 | 101 | ํค๋ณด๋ | 100000 | 2024-02-20 |
| ํจ์ | ์ค๋ช | ์์ |
|---|---|---|
| COUNT() | ๊ฐ์ | COUNT(*), COUNT(column) |
| SUM() | ํฉ๊ณ | SUM(amount) |
| AVG() | ํ๊ท | AVG(amount) |
| MAX() | ์ต๋๊ฐ | MAX(amount) |
| MIN() | ์ต์๊ฐ | MIN(amount) |
์ ์ฒด ๋ฐ์ดํฐ์ ๋ํ ์ง๊ณ:
SELECT
COUNT(*) AS ์ด_์ฃผ๋ฌธ์,
SUM(amount) AS ์ด_๋งค์ถ,
AVG(amount) AS ํ๊ท _์ฃผ๋ฌธ๊ธ์ก,
MAX(amount) AS ์ต๋_์ฃผ๋ฌธ๊ธ์ก,
MIN(amount) AS ์ต์_์ฃผ๋ฌธ๊ธ์ก
FROM orders;
| ์ด_์ฃผ๋ฌธ์ | ์ด_๋งค์ถ | ํ๊ท _์ฃผ๋ฌธ๊ธ์ก | ์ต๋_์ฃผ๋ฌธ๊ธ์ก | ์ต์_์ฃผ๋ฌธ๊ธ์ก |
|---|---|---|---|---|
| 6 | 3550000 | 591667 | 1500000 | 50000 |
SELECT
user_id,
COUNT(*) AS ์ฃผ๋ฌธ์,
SUM(amount) AS ์ด_์ฃผ๋ฌธ๊ธ์ก
FROM orders
GROUP BY user_id;
| user_id | ์ฃผ๋ฌธ์ | ์ด_์ฃผ๋ฌธ๊ธ์ก |
|---|---|---|
| 101 | 3 | 1650000 |
| 102 | 2 | 400000 |
| 103 | 1 | 1500000 |
SELECT
product,
COUNT(*) AS ํ๋งค์,
SUM(amount) AS ์ด_๋งค์ถ
FROM orders
GROUP BY product;
| product | ํ๋งค์ | ์ด_๋งค์ถ |
|---|---|---|
| ๋ ธํธ๋ถ | 2 | 3000000 |
| ๋ง์ฐ์ค | 1 | 50000 |
| ํค๋ณด๋ | 2 | 200000 |
| ๋ชจ๋ํฐ | 1 | 300000 |
SELECT
user_id,
product,
COUNT(*) AS ๊ตฌ๋งคํ์,
SUM(amount) AS ์ด์ก
FROM orders
GROUP BY user_id, product;
| user_id | product | ๊ตฌ๋งคํ์ | ์ด์ก |
|---|---|---|---|
| 101 | ๋ ธํธ๋ถ | 1 | 1500000 |
| 101 | ๋ง์ฐ์ค | 1 | 50000 |
| 101 | ํค๋ณด๋ | 1 | 100000 |
| 102 | ํค๋ณด๋ | 1 | 100000 |
| 102 | ๋ชจ๋ํฐ | 1 | 300000 |
| 103 | ๋ ธํธ๋ถ | 1 | 1500000 |
SELECT
DATE_FORMAT(order_date, '%Y-%m') AS ์,
COUNT(*) AS ์ฃผ๋ฌธ์,
SUM(amount) AS ๋งค์ถ
FROM orders
GROUP BY DATE_FORMAT(order_date, '%Y-%m');
| ์ | ์ฃผ๋ฌธ์ | ๋งค์ถ |
|---|---|---|
| 2024-01 | 3 | 1650000 |
| 2024-02 | 3 | 1900000 |
| DB | ์ฐ-์ ์ถ์ถ |
|---|---|
| MySQL | DATE_FORMAT(date, '%Y-%m') |
| PostgreSQL | TO_CHAR(date, 'YYYY-MM') |
| BigQuery | FORMAT_DATE('%Y-%m', date) |
| ์ | ์์ | ๋์ |
|---|---|---|
| WHERE | GROUP BY ์ | ๊ฐ๋ณ ํ |
| HAVING | GROUP BY ํ | ๊ทธ๋ฃน ๊ฒฐ๊ณผ |
SELECT
user_id,
COUNT(*) AS ์ฃผ๋ฌธ์,
SUM(amount) AS ์ด์ก
FROM orders
GROUP BY user_id
HAVING COUNT(*) >= 2;
| user_id | ์ฃผ๋ฌธ์ | ์ด์ก |
|---|---|---|
| 101 | 3 | 1650000 |
| 102 | 2 | 400000 |
-- 2024๋
์ฃผ๋ฌธ ์ค, ์ด์ก 100๋ง์ ์ด์์ธ ์ ์
SELECT
user_id,
SUM(amount) AS ์ด์ก
FROM orders
WHERE order_date >= '2024-01-01' -- ํ ํํฐ๋ง
GROUP BY user_id
HAVING SUM(amount) >= 1000000; -- ๊ทธ๋ฃน ํํฐ๋ง
SELECT
COUNT(*) AS ์ ์ฒดํ, -- NULL ํฌํจ
COUNT(user_id) AS user_id์, -- NULL ์ ์ธ
COUNT(DISTINCT user_id) AS ์ ์ ์ -- ์ค๋ณต ์ ์ธ
FROM orders;
| ์ ์ฒดํ | user_id์ | ์ ์ ์ |
|---|---|---|
| 6 | 6 | 3 |
-- ์ฃผ๋ฌธํ ์ ์ ์ (์ค๋ณต ์ ์ธ)
SELECT COUNT(DISTINCT user_id) AS ๊ตฌ๋งค_์ ์ ์
FROM orders;
SQL ์คํ ์์:
FROM โ ํ
์ด๋ธ ์ ํ
WHERE โ ํ ํํฐ๋ง
GROUP BY โ ๊ทธ๋ฃนํ
HAVING โ ๊ทธ๋ฃน ํํฐ๋ง
SELECT โ ์ปฌ๋ผ ์ ํ
ORDER BY โ ์ ๋ ฌ
LIMIT โ ๊ฐ์ ์ ํ
์ ์ค์ํด?
-- โ ์๋ฌ! SELECT์ ๋ณ์นญ์ WHERE์์ ๋ชป ์
SELECT user_id, SUM(amount) AS total
FROM orders
WHERE total > 100000 -- ์์ง total ์์!
GROUP BY user_id;
-- โ
HAVING ์ฌ์ฉ
SELECT user_id, SUM(amount) AS total
FROM orders
GROUP BY user_id
HAVING SUM(amount) > 100000;
์ ๋ต ๋ณด๊ธฐ์ํ๋ณ ํ๊ท ์ฃผ๋ฌธ ๊ธ์ก์ ๊ตฌํ์ธ์. ํ๊ท ๊ธ์ก ๋ด๋ฆผ์ฐจ์ ์ ๋ ฌ.
SELECT
product,
AVG(amount) AS avg_amount
FROM orders
GROUP BY product
ORDER BY avg_amount DESC;
์ ๋ต ๋ณด๊ธฐ์ด ์ฃผ๋ฌธ ๊ธ์ก์ด 50๋ง์ ์ด์์ธ ์ ์ ์ user_id์ ์ด ๊ธ์ก์ ๊ตฌํ์ธ์.
SELECT
user_id,
SUM(amount) AS total_amount
FROM orders
GROUP BY user_id
HAVING SUM(amount) >= 500000;
์ ๋ต ๋ณด๊ธฐ2024๋ 1์์ 2ํ ์ด์ ์ฃผ๋ฌธํ ์ ์ ์ user_id, ์ฃผ๋ฌธ ํ์, ์ด์ก์ ๊ตฌํ์ธ์.
SELECT
user_id,
COUNT(*) AS order_count,
SUM(amount) AS total_amount
FROM orders
WHERE order_date >= '2024-01-01'
AND order_date < '2024-02-01'
GROUP BY user_id
HAVING COUNT(*) >= 2;
์ ๋ต ๋ณด๊ธฐ์ ์ ๋ณ ์ด๋ฆ๊ณผ ์ด ์ฃผ๋ฌธ ๊ธ์ก์ ๊ตฌํ์ธ์. (users ํ ์ด๋ธ๊ณผ JOIN)
SELECT
u.name,
SUM(o.amount) AS total_amount
FROM users u
JOIN orders o ON u.user_id = o.user_id
GROUP BY u.user_id, u.name;
-- โ ์๋ฌ (์๊ฒฉ ๋ชจ๋์์)
SELECT user_id, product, SUM(amount)
FROM orders
GROUP BY user_id; -- product๋ GROUP BY์ ์์!
-- โ
์์
SELECT user_id, product, SUM(amount)
FROM orders
GROUP BY user_id, product;
-- โ ์๋ฌ
SELECT user_id, SUM(amount)
FROM orders
WHERE SUM(amount) > 100000 -- ์ง๊ณํจ์๋ WHERE์์ ๋ชป ์!
GROUP BY user_id;
-- โ
HAVING ์ฌ์ฉ
SELECT user_id, SUM(amount)
FROM orders
GROUP BY user_id
HAVING SUM(amount) > 100000;
-- amount๊ฐ NULL์ธ ํ์ด ์๋ค๋ฉด?
SELECT SUM(amount) FROM orders; -- NULL ํ์ ๋ฌด์๋จ
-- NULL์ 0์ผ๋ก ์ฒ๋ฆฌ
SELECT SUM(COALESCE(amount, 0)) FROM orders;
[์ง๊ณํจ์]
COUNT, SUM, AVG, MAX, MIN
[GROUP BY]
ํน์ ์ปฌ๋ผ ๊ธฐ์ค์ผ๋ก ๋ฐ์ดํฐ ๋ฌถ๊ธฐ
[HAVING]
๊ทธ๋ฃนํ ํ ํํฐ๋ง (WHERE๋ ๊ทธ๋ฃนํ ์ )
[์คํ์์]
FROM โ WHERE โ GROUP BY โ HAVING โ SELECT โ ORDER BY
[SQL ์๋ฆฌ์ฆ #3] ์๋ธ์ฟผ๋ฆฌ โ ์ฟผ๋ฆฌ ์์ ์ฟผ๋ฆฌ
๐ GROUP BY๋ ๋ฐ์ดํฐ ๋ถ์์ ๊ธฐ๋ณธ์ด๋ค.
"~๋ณ๋ก ์ง๊ณํด์ค"๋ผ๋ ์์ฒญ์ด ์ค๋ฉด GROUP BY๋ฅผ ๋ ์ฌ๋ฆฌ์!