본문 바로가기

SQL/LeetCode

LeetCode / 1251. Average Selling Price / MySQL (Easy) (IFNULL/ JOIN조건 : WHERE,AND)

728x90

📚문제

출처 : LeetCode(https://leetcode.com/problems/average-selling-price/)


📝풀이

# Write your MySQL query statement below
SELECT p.product_id
     , IFNULL(ROUND(SUM(p.price * u.units) / SUM(u.units), 2),0) AS average_price
FROM Prices p
LEFT JOIN UnitsSold u ON p.product_id = u.product_id 
AND (u.purchase_date BETWEEN p.start_date AND p.end_date)
GROUP BY p.product_id

 

그렇게 어렵지는 않은 문제지만

하나 주의해야할 것이 있다

 

문제상에 나오지 않은 prduct_id = 3일때도 고려를 해주어야 하는 것 같다

그래서 INNER JOIN이 아니라 LEFT JOIN을 해주어야한다

(Prices 테이블을 기준으로 LEFT JOIN 해야하는 이유가
product_id =3일 때 어느 기간동안 가격이 얼마다 라는 정보는 있지만
그 기간동안 물건이 팔렸다는 보장은 없음
간단하게 말하면 가격정보는 있지만 팔린 기록은 없을 수 있음
이 부분도 헷갈려서 곰곰이 생각해보고 알았다)

 

이런 경우에는 IFNULL 조건문을 사용하여 NULL값인 경우 0으로 표시해주면 된다

 

+ 그리고 중요한 것 

조인조건(ON)에 AND를 붙이는 것과 

WHERE 구문으로 필터링 하는 것은 동일하다고 생각했는데

결론적으론

INNER JOIN에선 동일하지만 OUTER JOIN에서는 아니다

 

[ON vs WHERE]

ON : JOIN 을 하기 전 필터링을 한다 (=ON 조건으로 필터링이 된 레코들간 JOIN이 이뤄진다)

WHERE : JOIN 을 한 후 필터링을 한다 (=JOIN을 한 결과에서 WHERE 조건절로 필터링이 이뤄진다)

 

왼 : table1 t1 / 오 : table2 t2

위 두가지의 테이블을 

 

1) 그냥 ON 조건(t1.col1 = t2.col1)만으로 LEFT JOIN했을 때

t1의 행은 모두 표시하고

t2에는 col1=3인 데이터가 없으므로 NULL값으로 표시

 

2) ON 조건에 AND를 붙여서 t2.col2 = '일' 이라는 조건을 추가해줬을 때

 

t1의 전체 행과 t2에서 col2가 '일'인 행만 LEFT JOIN 해줌

ON 조건은 JOIN전 필터링 되는 기준

 

3) WHERE 구문에 조건을 추가했을 때

처음 경우 (LEFT JOIN만 해주었을 때)의 값과 동일하게 나온 뒤

WHERE 조건으로 해당행만 추출 

두 번째 경우와 세 번째 경우의 가장 큰 차이점은

두번째 경우는 해당 경우만 JOIN해주고 나머지는 NULL값 처리

(NULL값 포함 모든 행이 조회됨)

세번째 경우는 그대로 JOIN 해주고 해당 행만 검색 

(해당 행만 조회됨)

 

무슨 차이가 있는지 , 또 내가 잘못알고 있었던건지 

헷갈리는 부분이었는데 

구글링도 해보고 설명이 잘 되어있는 글도 참고한 덕분에 

중요한 부분을 짚고 넘어갈 수 있었다

 

📌핵심 

1. JOIN의 ON 조건과 WHERE 구문의 차이점

2. IFNULL의 사용

3. Prices 테이블 기준으 LEFT JOIN

 

참고링크 출처 : https://developyo.tistory.com/121

728x90