<์ค๋์ ํ์ต>
- SQL ์ฑ์ทจ๋ ํ๊ฐ ์ํ/๋ฆฌ๋ทฐ
- SQL ์ฝ๋์นดํ
https://tjsdud7032.tistory.com/41
[SQL ์ฝ๋์นดํ] ๋ ๋ฒจ 2 / 11~30
11. ์ฌ๋ฌ ๊ธฐ์ค์ผ๋ก ์ ๋ ฌํ๊ธฐ๋ฌธ์ ๋งํฌhttps://school.programmers.co.kr/learn/courses/30/lessons/59404์ ๋ต์ฝ๋select ANIMAL_ID, NAME, DATETIMEfrom ANIMAL_INSorder by NAME, DATETIME desc;12. ์ด๋ฆ์ el์ด ๋ค์ด๊ฐ๋ ๋๋ฌผ ์ฐพ๊ธฐ๋ฌธ์ ๋ง
tjsdud7032.tistory.com
- Python ํ์ต ๋ธ๋ก๊ทธ ์์ฑ: Chapter 01
https://tjsdud7032.tistory.com/39
Chapter 1. ์ฝ๋ฉ์ ๋ฌด์์ด๊ณ , ๋ฐ์ดํฐ ๋ถ์์ ์ ํ์ํ๊ฐ
์ฝ๋ฉ๊ณผ ํ์ด์ฌ, ๊ทธ๋ฆฌ๊ณ ๋ฐ์ดํฐ ๋ถ์1. ์ด ๊ฐ์ข๋ ์ด๋ค ์ฌ๋์ ์ํ๊ฐ์ด ์๋ฆฌ์ฆ๋ ๋ค์๊ณผ ๊ฐ์ ํ์ต์๋ฅผ ๋์์ผ๋ก ํฉ๋๋ค.ํ๋ก๊ทธ๋๋ฐ์ ํ ๋ฒ๋ ํด๋ณธ ์ ์๋ ์ฌ๋์ซ์๋ ์ฝ๋๋ ์ด๋ ต์ง๋ง, ์ดํด
tjsdud7032.tistory.com
<ํ์ต๋ด์ฉ ์ ๋ฆฌ>
<SQL> ์ฑ์ทจ๋ ํ๊ฐ; ์ค์ต๋ฌธ์
๋ฌธ์ 11) ์ฃผ๋ฌธ ๋ฆฌ์คํธ ๋ผ๋ฒจ
CASE WHEN ํ์ฉ ๋ฌธ์
(CASE ๊ตฌ๋ฌธ ์ดํด ์๋ฃ)
orders ํ ์ด๋ธ์์ ์๋ ์กฐ๊ฑด์ ๋ง์กฑํ๋ ์ฃผ๋ฌธ๋ง ์ถ๋ ฅํ์ธ์.
์กฐ๊ฑด:
`order_date`๊ฐ **'2026-01-05' ~ '2026-01-15' (ํฌํจ)
์ถ๋ ฅ ์ปฌ๋ผ:
- `order_id`
- `order_date`
- `channel`
- `order_status`
- `coupon_flag`
- coupon_code๊ฐ NULL์ด๋ฉด `'no_coupon'`
- ์๋๋ฉด `'coupon_used'`
- `delivery_days_clean`
- `delivery_days`๊ฐ NULL์ด๋ฉด 0, ์๋๋ฉด `delivery_days`
์ ๋ ฌ: `order_date` ์ค๋ฆ์ฐจ์, `order_id` ์ค๋ฆ์ฐจ์
SELECT order_id
, order_date
, channel
, order_status
, CASE WHEN coupon_code IS NULL THEN 'no_coupon'
ELSE coupon_code
END coupon_flag
, CASE WHEN delivery_days IS NULL THEN 0
ELSE delivery_days
END delivery_days_clean
-- ifnull(delivery_days, 0) as delivery_days_clean ์ด๊ฒ๋ ๊ฐ๋ฅ
FROM test.orders
WHERE order_date BETWEEN '2026-01-05' AND '2026-01-15'
ORDER BY order_date, order_id;
๋ฌธ์ 12) ์ง์ญ๋ณ ๋งค์ถ ์์ฝ
1. ์ง๊ณํจ์ ๋ฆฌ์คํธ ์ฌ์ฉ
2. JOIN
(์ดํด ์๋ฃ)
orders + order_items๋ฅผ ์ด์ฉํด์, ์๋ฃ๋ ์ฃผ๋ฌธ๋ง ์ง์ญ๋ณ๋ก ์์ฝํ์ธ์.
์กฐ๊ฑด: `order_status = 'completed'`
๋งค์ถ(`net_revenue`) ์ ์:
`unit_price * quantity * (1 - discount_rate)`
์ถ๋ ฅ ์ปฌ๋ผ:
- `ship_region`
- `order_cnt` : ์ง์ญ๋ณ **๊ณ ์ ์ฃผ๋ฌธ ์**
- `customer_cnt` : ์ง์ญ๋ณ **๊ณ ์ ๊ณ ๊ฐ ์**
- `net_revenue` : ์ง์ญ๋ณ ๋งค์ถ ํฉ๊ณ
์ถ๊ฐ ์กฐ๊ฑด(HAVING): `order_cnt >= 2` ์ธ ์ง์ญ๋ง
์ ๋ ฌ: `net_revenue` ๋ด๋ฆผ์ฐจ์, `ship_region` ์ค๋ฆ์ฐจ์
`orders` ํ ์ด๋ธ ๋ณ์นญ : o / `order_items` ํ ์ด๋ธ ๋ณ์นญ : oi
SELECT o.ship_region
, COUNT(DISTINCT o.order_id) AS order_cnt
, COUNT(DISTINCT o.customer_id) AS customer_cnt
, SUM(oi.unit_price * oi.quantity * (1-oi.discount_rate))
AS net_revenue
FROM test.orders o
LEFT JOIN order_items oi
ON o.order_id = oi.order_id
WHERE o.order_status = 'completed'
GROUP BY o.ship_region
HAVING COUNT(DISTINCT o.order_id) >= 2
ORDER BY net_revenue DESC, o.ship_region;
๋ฌธ์ 13) ๊ฒฐ์ ๋ด์ญ ๋ถ์ด๊ธฐ
JOIN์ ์กฐ๊ฑด๋ฌธ WHERE / ON์ ๋ถ์ด๊ธฐ
(์ดํด ์๋ฃ)
`orders`๋ฅผ ๊ธฐ์ค์ผ๋ก ๊ฒฐ์ ์ ๋ณด๋ฅผ ๋ถ์ด๋, ๊ฒฐ์ ๊ฐ ์๋ ์ฃผ๋ฌธ๋ ๊ฒฐ๊ณผ์ ๋จ๊ฒจ์ผ ํฉ๋๋ค.
๋์ ์ฃผ๋ฌธ:
- `order_date`๊ฐ '2026-01-05' ~ '2026-01-31' (ํฌํจ)
- `payments`๋ `payment_status='paid'` ์ธ ๊ฒฐ์ ๋ง** ๋ถ์ด์ธ์.
์ถ๋ ฅ ์ปฌ๋ผ:
- `order_id`, `order_status`, `order_date`
- `payment_id`, `paid_at`, `amount` (๊ฒฐ์ ์์ผ๋ฉด NULL)
์ ๋ ฌ: `order_date`, `order_id`, `paid_at` ์ค๋ฆ์ฐจ์
`orders` ํ ์ด๋ธ ๋ณ์นญ : o / `payments` ํ ์ด๋ธ ๋ณ์นญ : p
SELECT o.order_id, o.order_status, o.order_date,
p.payment_id, p.paid_at, p.amount
FROM test.orders o
LEFT JOIN test.payments p
ON o.order_id=p.order_id
AND p.payment_status='paid'
WHERE o.order_date BETWEEN '2026-01-05' AND '2026-01-31'
ORDER BY order_date, order_id, paid_at;
๋ฌธ์ 14) SQL ์นดํ ๊ณ ๋ฆฌ ๊ตฌ๋งค ๊ณ ๊ฐ ์ฐพ๊ธฐ
JOIN ์ฌ๋ฌ ๋ฒ ํ๊ธฐ
WHERE IN() ์๋ธ์ฟผ๋ฆฌ ์กฐ๊ฑด ์ฌ์ฉํ๊ธฐ
<์ค๋ต๋ ธํธ>
- ์ฌ์ฉํด์ผ ํ๋ ํ ์ด๋ธ๋ค์ด ๊ณตํต ์ปฌ๋ผ์ด ์์ ๋๋ ์ค๊ฐ์ ์ด์ด์ง๋ ์ปฌ๋ผ์ผ๋ก ์ด์ด์ ๋ถ์ด๋ฉด ๋๋ค.
ex. orders ←(order_id)→ order_items ←(book_id)→ books
- ํ ์กฐ๊ฑด์ WHERE / ON ์ด๋์ ์ธ ๊ฑด์ง ์ ํ์ ํ๊ธฐ.
์๋ ์กฐ๊ฑด์ ๋ง์กฑํ๋ ๊ณ ๊ฐ์ ์ฐพ์ผ์ธ์.
์กฐ๊ฑด:
- ๊ณ ๊ฐ์ด **completed ์ฃผ๋ฌธ**์ ํ ์ ์ด ์๊ณ
- ๊ทธ ์ฃผ๋ฌธ์ ํฌํจ๋ ์ฑ
์ค **`books.category = 'sql'`** ์ด **ํ๋๋ผ๋** ํฌํจ
์ถ๋ ฅ ์ปฌ๋ผ: `customer_id`, `customer_name`, `segment`
์ ๋ ฌ: `customer_id` ์ค๋ฆ์ฐจ์
- `orders` ํ
์ด๋ธ ๋ณ์นญ : o / `order_items` ํ
์ด๋ธ ๋ณ์นญ : oi / `books` ํ
์ด๋ธ ๋ณ์นญ : b / `customers` ํ
์ด๋ธ ๋ณ์นญ c
ํํธ: EXISTS ๋๋ IN ๋ฐฉ์ ๋ ๋ค ํ์ฉ
-- IN() ์ฌ์ฉ
SELECT c.customer_id, c.customer_name, c.segment
FROM test.customers c
WHERE c.customer_id IN (
SELECT o.customer_id
FROM test.orders o
LEFT JOIN test.order_items oi
ON o.order_id = oi.order_id
LEFT JOIN test.books b
ON oi.book_id = b.book_id
AND b.category = 'sql'
WHERE o.order_status = 'completed'
AND b.category = 'sql'
)
ORDER BY c.customer_id;
-- EXISTS ์ฌ์ฉ
SELECT c.customer_id, c.customer_name, c.segment
FROM test.customers c
WHERE EXISTS (
SELECT *
FROM test.orders o
LEFT JOIN test.order_items oi
ON o.order_id = oi.order_id
LEFT JOIN test.books b
ON oi.book_id = b.book_id
WHERE o.customer_id = c.customer_id
AND o.order_status = 'completed'
AND b.category = 'sql')
๋ฌธ์ 15) ๊ณ ๊ฐ๋ณ ์ฃผ๋ฌธ ์๋ฅผ ํ ์ ์ง๋ก ๋ถ์ด๊ธฐ
ํฌ์ธํธ! ํ์ ์ง = ์๋์ฐ ํจ์, group by ์ฌ์ฉ X
`orders`์์ ๊ฐ ์ฃผ๋ฌธ ํ(ํ ์ ์ง)๋ง๋ค, ํด๋น ๊ณ ๊ฐ์ ์ฃผ๋ฌธ ์๋ฅผ ๋ถ์ฌ ์ถ๋ ฅํ์ธ์.
์ถ๋ ฅ ์ปฌ๋ผ:
- `order_id`, `customer_id`, `order_date`, `order_status`
- `customer_order_cnt` : ๊ณ ๊ฐ๋ณ ์ฃผ๋ฌธ ์
์ ๋ ฌ: `customer_id`, `order_date`, `order_id` ์ค๋ฆ์ฐจ์
select
order_id, customer_id, order_date, order_status,
count(*) over (partition by customer_id) as customer_order_cnt
from test.orders
order by customer_id, order_date, order_id;
<๋ค์์ฃผ ํ์ต>
- ํ์ด์ฌ ํ์ต์ฃผ๊ฐ ์์
- SQL ์ฝ๋์นดํ ๋ ๋ฒจ3 ์์
- ์ฌ์ ์บ ํ ํ์คํธ / ๋ฌ๋ฆฌ๊ธฐ๋ฐ ๋ฌธ์ ํ์ด
'์คํ๋ฅดํ ๋ด์ผ๋ฐฐ์์บ ํ(25.12.01~)' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
| ์คํ๋ฅดํ ๋ด์ผ๋ฐฐ์์บ ํ_๋ณธ์บ ํ_data11๊ธฐ ๊น์ ์_TIL_Day 10 (0) | 2026.01.06 |
|---|---|
| ์คํ๋ฅดํ ๋ด์ผ๋ฐฐ์์บ ํ_๋ณธ์บ ํ_data11๊ธฐ ๊น์ ์_TIL_Day 9 (0) | 2026.01.05 |
| [SQL ์ฝ๋์นดํ] ๋ ๋ฒจ 2 / 11~30 (0) | 2026.01.02 |
| ์คํ๋ฅดํ ๋ด์ผ๋ฐฐ์์บ ํ_๋ณธ์บ ํ_data11๊ธฐ ๊น์ ์_TIL_Day 7 (0) | 2026.01.01 |
| [SQL ์ฝ๋์นดํ] ๋ ๋ฒจ 1 / 1~10 (0) | 2025.12.31 |