์ŠคํŒŒ๋ฅดํƒ€ ๋‚ด์ผ๋ฐฐ์›€์บ ํ”„(25.12.01~)

์ŠคํŒŒ๋ฅดํƒ€ ๋‚ด์ผ๋ฐฐ์›€์บ ํ”„_๋ณธ์บ ํ”„_data11๊ธฐ ๊น€์„ ์˜_TIL_Day 8

0๏ธโƒฃ 2026. 1. 2. 23:04

<์˜ค๋Š˜์˜ ํ•™์Šต>

 

[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

 

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 ์‹œ์ž‘
  • ์‚ฌ์ „์บ ํ”„ ํ€˜์ŠคํŠธ / ๋‹ฌ๋ฆฌ๊ธฐ๋ฐ˜ ๋ฌธ์ œ ํ’€์ด