Programing Language/SQL
3. ์๋์ฐ ํจ์ ๋ฌธ์
Data-SSung
2025. 6. 14. 23:35
๋ฐ์ํ
๐ข ์ฐ์ต๋ฌธ์ 3-1: ๊ธฐ๋ณธ ์์
- RANK() : ๋์ผํ ์ ์์ ๋ํด์ ๊ฐ์ ์์ ๋งค๊น
=> ์ํ๋ณ ์ด ํ๋งค๋ ์์์ ์ ์ - ROW_NUMBER() : ๋์ผํ ์ ์์ฌ๋ ํ๋์ ์์๋ง ๋งค๊น
=> ์นดํ ๊ณ ๋ฆฌ ๋ด ๊ณ ๊ฐ๋ณ ์์์ ์ ์
[๋ฌธ์ ]
์ํ๋ณ ์ด ํ๋งค๋์ ๊ตฌํ๊ณ , ํ๋งค๋ ์์๋ฅผ ๋งค๊ธฐ์์ค.
[ํ
์ด๋ธ ๊ตฌ์กฐ]
products: product_id, product_name, category
order_items: order_item_id, order_id, product_id, quantity
-- ๋ต
SELECT A.product_id, A.product_name
, SUM(B.quantity) TOTAL_QUNAT
, RANK() OVER(ORDER BY SUM(B.quantity) DESC) RN
FROM PRODUCTS A
INNER JOIN ORDER_ITEMS B
ON A.PRODUCT_ID = B.PRODUCT_ID
GROUP BY A.product_id, A.product_name
ORDER BY RN DESC
์ค์ ๋ฌธ์ 3-1: ์๋ณ ๋งค์ถ ์ฑ์ฅ๋ฅ ๊ณผ ์ด๋ํ๊ท
- GROUPBYํ ๋, (YEAR, MONTH)๊ฐ ์ธ๋ฑ์ค๋ก ์ฌ์ฉ๋์ด DATE_FORMAT๋ณด๋ค๋ ์ฐ์ฐ๋์ด ์ ์ด ํจ์จ์ ์
- ์ ์ ๋๋น : LAGํจ์๋ฅผ ์จ์ ์ง์ ๋ฌ ์ ๋ณด ๊ฐ์ ธ์ค๊ธฐ ORDER BY ๋ ์๋ณ ์ค๋ฆ์ฐจ์ ์ค์
- 3๊ฐ์ ์ด๋ ํ๊ท : AVGํจ์ ์ฌ์ฉ ORDER BY ์๋ณ ์ค๋ฆ์ฐจ์ ์ค์ ํ 2๊ฐ ์ง์ ๋ฌ ํฉ๊ณ ๊ฐ์ ธ์ค๊ธฐ
- ์ง์ ๋ฌ ํฉ๊ณ ์ ๋ณด ๊ฐ์ ธ์ค๊ธฐ : ROWS 2 PRECEDING(์์ ์ด์ ์)
- ์ฐ์ด ๋๋น ๋์ ์ฆ๊ฐ๋ฅ : ์ ์ ๋๋น ์ฆ๊ฐ์จ๊ณผ ๋ฐฉ์์ ๋์ผํ๋, ์ฐ์ด ๊ฐ์ FIRST_VALUE ํจ์ ์ฌ์ฉ
[๋ฌธ์ ]
2023๋
์๋ณ ๋งค์ถ ๋ฐ์ดํฐ๋ฅผ ๋ถ์ํ์ฌ ๋ค์์ ๊ตฌํ์์ค:
1. ๊ฐ ์์ ์ด ๋งค์ถ
2. ์ ์ ๋๋น ์ฆ๊ฐ๋ฅ (%) : ์ ์ ๋๋น ์ฆ๊ฐ๋ฅ = (ํ์ฌ์ ๋งค์ถ - ์ ์ ๋งค์ถ) / ์ ์ ๋งค์ถ × 100
3. 3๊ฐ์ ์ด๋ํ๊ท
4. ์ฐ์ด ๋๋น ๋์ ์ฆ๊ฐ๋ฅ
๊ฒฐ๊ณผ๋ ์ ์์๋๋ก ์ ๋ ฌํ์์ค.
[ํ
์ด๋ธ ๊ตฌ์กฐ]
orders: order_id, customer_id, order_date, amount, status
-- ๋ต
SELECT YEAR(ORDER_DATE) ORDER_YEAR
, MONTH(ORDER_DATE) ORDER_MONTH
-- ๊ฐ ์์ ์ด ๋งค์ถ
, SUM(AMOUNT) SALE_SUM
-- ์ ์ ๋๋น ์ฆ๊ฐ๋ฅ
, ROUND(
(SUM(AMOUNT) - LAG(SUM(AMOUNT)) OVER(ORDER BY YEAR(ORDER_DATE), MONTH(ORDER_DATE)) )
/LAG(SUM(AMOUNT)) OVER(ORDER BY YEAR(ORDER_DATE), MONTH(ORDER_DATE)) *100
,2) SALE_RATE
-- 3๊ฐ์ ์ด๋ํ๊ท
, ROUND(
AVG(SUM(AMOUNT))
OVER(ORDER BY YEAR(ORDER_DATE), MONTH(ORDER_DATE))
ROWS 2 PRECEDING)
,2) THREE_SALE_AVG
-- ์ฐ์ด ๋๋น ๋์ ์ฆ๊ฐ๋ฅ
, ROUND(
(SUM(AMOUNT) - FIRST_VALUE(SUM(AMOUNT)) OVER(ORDER BY YEAR(ORDER_DATE), MONTH(ORDER_DATE)) )
/FIRST_VALUE(SUM(AMOUNT)) OVER(ORDER BY YEAR(ORDER_DATE), MONTH(ORDER_DATE))*100
,2) SALE_RATE2
FROM ORDERS
WHERE ORDER_DATE >= '2023-01-01'
AND ORDER_DATE < '2024-01-01'
AND STATUS = 'COMPLETED'
GROUP BY YEAR(ORDER_DATE)
, MONTH(ORDER_DATE)
ORDER BY ORDER_YEAR, ORDER_MONTH
;
๐ฏ ์ํฉ๋ณ ์ต์ ์ ํ
๐ ์ถ๋ ฅ ํํ๊ฐ ์ค์ํ ๊ฒฝ์ฐ
sql
-- ์๊ตฌ์ฌํญ: "2023-01", "2023-02" ํํ๋ก ์ถ๋ ฅ
DATE_FORMAT(ORDER_DATE, '%Y-%m') โ
-- vs
CONCAT(YEAR(ORDER_DATE), '-', LPAD(MONTH(ORDER_DATE), 2, '0')) โ (๋ณต์กํจ)
๐ ์ฑ๋ฅ์ด ์ค์ํ ๊ฒฝ์ฐ
sql
-- ๋์ฉ๋ ๋ฐ์ดํฐ + ์ธ๋ฑ์ค ํ์ฉ
YEAR(ORDER_DATE), MONTH(ORDER_DATE) โ
-- vs
DATE_FORMAT(ORDER_DATE, '%Y-%m') โ (๋ฌธ์์ด ์ฐ์ฐ ๋ถํ)
๐ ์ฑ๋ฅ ์ฐจ์ด ์ด์
DATE_FORMAT์ด ๋๋ฆฐ ์ด์ :
- ๋ฌธ์์ด ๋ณํ ์ฐ์ฐ
- ์ธ๋ฑ์ค ํ์ฉ๋ ๋ฎ์
- ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋ ์ฆ๊ฐ
YEAR, MONTH๊ฐ ๋น ๋ฅธ ์ด์ :
- ์ ์ ์ฐ์ฐ
- ๋ ์ง ์ธ๋ฑ์ค ์ง์ ํ์ฉ
- ๋ฉ๋ชจ๋ฆฌ ํจ์จ์
๐ก ์ค๋ฌด ๊ถ์ฅ์ฌํญ
sql
-- ํ๋ฉด ์ถ๋ ฅ์ฉ: DATE_FORMAT ์ฌ์ฉ
SELECT DATE_FORMAT(ORDER_DATE, '%Y-%m') AS SALES_MONTH
-- ์ง๊ณ/๋ถ์์ฉ: YEAR, MONTH ์ฌ์ฉ
GROUP BY YEAR(ORDER_DATE), MONTH(ORDER_DATE)
๊ฒฐ๋ก : ๋ฌธ์ ์์ ํน๋ณํ ์ถ๋ ฅ ํํ๋ฅผ ์๊ตฌํ์ง ์์ผ๋ฉด YEAR, MONTH๊ฐ ๋ ํจ์จ์ ์ด์์!
๋ฐ์ํ