Growth 🌳/Practice πŸ’»

[ν”„λ‘œκ·Έλž˜λ¨ΈμŠ€] μƒν’ˆμ„ κ΅¬λ§€ν•œ νšŒμ› λΉ„μœ¨ κ΅¬ν•˜κΈ° (23.06.13 풀이 μΆ”κ°€)

μΈ” 2023. 1. 10. 02:58

πŸ“’ λ³Έ ν¬μŠ€νŒ…μ— ν™œμš©λ˜λŠ” κΈ°λ³Έ 문제 및 자료 μΆœμ²˜λŠ”

       ν”„λ‘œκ·Έλž˜λ¨ΈμŠ€ μ½”λ”©ν…ŒμŠ€νŠΈ μ—°μŠ΅,   
       https://school.programmers.co.kr/learn/challenges?page=1&languages=mysql%2Coracle
μž„μ„ λ°νž™λ‹ˆλ‹€.


β–  λ¬Έμ œ

문제 μ„€λͺ…

λ‹€μŒμ€ μ–΄λŠ 의λ₯˜ μ‡Όν•‘λͺ°μ— κ°€μž…ν•œ νšŒμ› 정보λ₯Ό 담은 USER_INFO ν…Œμ΄λΈ”κ³Ό 온라인 μƒν’ˆ 판맀 정보λ₯Ό 담은 ONLINE_ SALE ν…Œμ΄λΈ” μž…λ‹ˆλ‹€.

USER_INFO ν…Œμ΄λΈ”μ€ μ•„λž˜μ™€ 같은 ꡬ쑰둜 λ˜μ–΄μžˆλ©° USER_ID, GENDER, AGE, JOINEDλŠ” 각각 νšŒμ› ID, 성별, λ‚˜μ΄, κ°€μž…μΌμ„ λ‚˜νƒ€λƒ…λ‹ˆλ‹€.

 

Column name Type Nullable
USER_ID INTEGER FALSE
GENDER TINYINT(1) TRUE
AGE INTEGER TRUE
JOINED DATE FALSE

GENDER μ»¬λŸΌμ€ λΉ„μ–΄μžˆκ±°λ‚˜ 0 λ˜λŠ” 1의 값을 가지며 0인 경우 λ‚¨μžλ₯Ό, 1인 κ²½μš°λŠ” μ—¬μžλ₯Ό λ‚˜νƒ€λƒ…λ‹ˆλ‹€.

ONLINE_SALE ν…Œμ΄λΈ”μ€ μ•„λž˜μ™€ 같은 ꡬ쑰둜 λ˜μ–΄μžˆμœΌλ©° ONLINE_SALE_ID, USER_ID, PRODUCT_ID, SALES_ AMOUNT, SALES_DATEλŠ” 각각 온라인 μƒν’ˆ 판맀 ID, νšŒμ› ID, μƒν’ˆ ID, νŒλ§€λŸ‰, νŒλ§€μΌμ„ λ‚˜νƒ€λƒ…λ‹ˆλ‹€.

Column name Type Nullable
ONLINE_SALE_ID INTEGER FALSE
USER_ID INTEGER FALSE
PRODUCT_ID INTEGER FALSE
SALES_AMOUNT INTEGER FALSE
SALES_DATE DATE FALSE

λ™μΌν•œ λ‚ μ§œ, νšŒμ› ID, μƒν’ˆ ID 쑰합에 λŒ€ν•΄μ„œλŠ” ν•˜λ‚˜μ˜ 판맀 λ°μ΄ν„°λ§Œ μ‘΄μž¬ν•©λ‹ˆλ‹€.


문제 

USER_INFO ν…Œμ΄λΈ”κ³Ό ONLINE_SALE ν…Œμ΄λΈ”μ—μ„œ 2021년에 κ°€μž…ν•œ 전체 νšŒμ›λ“€ 쀑 μƒν’ˆμ„ κ΅¬λ§€ν•œ νšŒμ›μˆ˜μ™€ μƒν’ˆμ„ κ΅¬λ§€ν•œ νšŒμ›μ˜ λΉ„μœ¨(=2021년에 κ°€μž…ν•œ νšŒμ› 쀑 μƒν’ˆμ„ κ΅¬λ§€ν•œ νšŒμ›μˆ˜ / 2021년에 κ°€μž…ν•œ 전체 νšŒμ› 수)을 λ…„, μ›” λ³„λ‘œ 좜λ ₯ν•˜λŠ” SQL문을 μž‘μ„±ν•΄μ£Όμ„Έμš”. μƒν’ˆμ„ κ΅¬λ§€ν•œ νšŒμ›μ˜ λΉ„μœ¨μ€ μ†Œμˆ˜μ  λ‘λ²ˆμ§Έμžλ¦¬μ—μ„œ λ°˜μ˜¬λ¦Όν•˜κ³ , 전체 κ²°κ³ΌλŠ” 년을 κΈ°μ€€μœΌλ‘œ μ˜€λ¦„μ°¨μˆœ μ •λ ¬ν•΄μ£Όμ‹œκ³  년이 κ°™λ‹€λ©΄ 월을 κΈ°μ€€μœΌλ‘œ μ˜€λ¦„μ°¨μˆœ μ •λ ¬ν•΄μ£Όμ„Έμš”.


 

β–  ν’€μ΄

  문제 μš”κ΅¬μ‚¬ν•­  

USER_INFO ν…Œμ΄λΈ”κ³Ό ONLINE_SALE ν…Œμ΄λΈ”μ—μ„œ

2021년에 κ°€μž…ν•œ 전체 νšŒμ›λ“€ 쀑 μƒν’ˆμ„ κ΅¬λ§€ν•œ νšŒμ›μˆ˜μ™€ μƒν’ˆμ„ κ΅¬λ§€ν•œ νšŒμ›μ˜ λΉ„μœ¨

(=2021년에 κ°€μž…ν•œ νšŒμ› 쀑 μƒν’ˆμ„ κ΅¬λ§€ν•œ νšŒμ›μˆ˜ / 2021년에 κ°€μž…ν•œ 전체 νšŒμ› 수)을 λ…„, μ›” λ³„λ‘œ 좜λ ₯

 

> λΉ„μœ¨μ˜ λΆ„λͺ¨, λΆ„μž 데이터 μˆ˜λŸ‰μ— λͺ¨λ‘ '2021년에 κ°€μž…ν•œ' νšŒμ›μ΄λΌλŠ” 쑰건이 λΆ€μ—¬λ˜μ—ˆλ‹€.

   μ΄ 쑰건을 쿼리둜 잘 ν’€μ–΄λ‚΄λŠ” 것이 μ€‘μš”ν–ˆλ‹€.

         <λΆ„λͺ¨> λŠ” (2021λ…„ κ°€μž…μžμ΄λ©΄μ„œ) ONLINE_SALE ν…Œμ΄λΈ”μ—μ„œ 2021λ…„ ꡬ맀 νšŒμ›μ˜ 수λ₯Ό μΆ”μΆœν•΄μ•Όν•˜κ³ 

          <λΆ„μž> λŠ” USER_INFO ν…Œμ΄λΈ”μ—μ„œ 2021λ…„ κ°€μž… νšŒμ›μ˜ 수λ₯Ό μΆ”μΆœ.

 

> 쿼리 μ‹€ν–‰ μˆœμ„œλ₯Ό μƒκ°ν–ˆμ„ λ•Œ,  ONLINE_SALE ν…Œμ΄λΈ” λ°μ΄ν„°μ—μ„œ  USER_INFOμ—μ„œ 2021λ…„ κ°€μž… νšŒμ›λ§Œμ„ λŒ€μƒμœΌλ‘œ ν…Œμ΄λΈ” 데이터λ₯Ό κ΅¬ν•˜κΈ° μœ„ν•΄ USER_INFO ν…Œμ΄λΈ”μ— JOINED λ‚ μ§œ κΈ°κ°„ 쑰건 +  INNER JOIN 적용 

 

> WHEREμ ˆμ— κ°€μž…μ‹œκΈ° 쑰건은 이전에 ν’€μ—ˆλ˜ 문제처럼 DATE_FORMAT() μ•„λ‹Œ BETWEEN ~ AND 문법 μ‚¬μš©

 

> λΆ„λͺ¨μ— USER_INFO ν…Œμ΄λΈ”μ„ λŒ€μƒμœΌλ‘œ 2021λ…„ κ°€μž…μž 수만 λ½‘μ•„μ£ΌλŠ” μ„œλΈŒμΏΌλ¦¬λ₯Ό μ‚¬μš©ν•œ 것이 풀이에 제일 μ‹œμž‘μ μ΄ λ˜μ—ˆλ˜ 것 κ°™λ‹€. 

 

μƒν’ˆμ„ κ΅¬λ§€ν•œ νšŒμ›μ˜ λΉ„μœ¨μ€ μ†Œμˆ˜μ  λ‘λ²ˆμ§Έμžλ¦¬μ—μ„œ 반올림   > SELECTμ ˆμ—μ„œ ROUND() ν•¨μˆ˜ μ‚¬μš©

전체 κ²°κ³ΌλŠ” 년을 κΈ°μ€€μœΌλ‘œ μ˜€λ¦„μ°¨μˆœ μ •λ ¬                                     > 정렬쑰건 1

년이 κ°™λ‹€λ©΄ 월을 κΈ°μ€€μœΌλ‘œ μ˜€λ¦„μ°¨μˆœ μ •λ ¬                                     > 정렬쑰건 2

 

SELECT DATE_FORMAT(OS.SALES_DATE, '%Y') YEAR, 
DATE_FORMAT(OS.SALES_DATE, '%m') MONTH,
COUNT(DISTINCT OS.USER_ID) PUCHASED_USERS
,ROUND(COUNT(DISTINCT OS.USER_ID) / (SELECT COUNT(DISTINCT USER_ID) 
                                     FROM USER_INFO
                                     WHERE JOINED BETWEEN '2021-01-01 00:00:00'
                                     AND '2021-12-31 23:59:59'), 1) PUCHASED_RATIO
 FROM ONLINE_SALE OS
 INNER JOIN (SELECT USER_ID, JOINED 
            FROM USER_INFO
            WHERE JOINED BETWEEN '2021-01-01 00:00:00' AND '2021-12-31 23:59:59') UI
 ON OS.USER_ID = UI.USER_ID
 GROUP BY 1, 2
 ORDER BY 1, 2

 

βœ” μΆ”κ°€ : λ‚ μ§œν•¨μˆ˜ ν™œμš©ν•΄μ„œ μ½”λ“œ κ°„λ‹¨νžˆ ν•˜κΈ° (2023.06.13 풀이)

SELECT YEAR(OS.SALES_DATE) AS YEAR
      ,MONTH(OS.SALES_DATE) AS MONTH
      ,COUNT(DISTINCT OS.USER_ID) AS PUCHASED_USERS
      ,ROUND((COUNT(DISTINCT OS.USER_ID) / (SELECT COUNT(DISTINCT USER_ID)
                                            FROM USER_INFO
                                            WHERE YEAR(JOINED) = '2021')), 1) AS PUCHASED_RATIO
 FROM ONLINE_SALE OS
 JOIN USER_INFO UI
 ON OS.USER_ID = UI.USER_ID AND YEAR(UI.JOINED) = '2021'
 GROUP BY 1, 2
 ORDER BY 1, 2;

μΆ”κ°€ ν’€μ΄μ—μ„œλŠ” 쑰인할 ν…Œμ΄λΈ”μ— user_infoμ—μ„œ κ°€μ Έμ˜¬ λ•Œ κ°€μž…λ…„λ„ = 2021 쑰건을 κ±Έμ–΄μ£ΌλŠ” λŒ€μ‹ 

쑰인 κ³Όμ •μ—μ„œ κ°€μž…λ…„λ„κ°€ 2021년인 user의 user_id만 μ‘°μΈλ˜λ„λ‘ ν•΄λ΄€λ‹€.