본문 바로가기

Database

[SQL] JOIN에서 WHERE과 ON 간 필터링 순서차이

반응형

LeetCode의 SQL문제를 풀던 중, 일부 테스트 코드를 통과하지 못하는 결과가 나와, 다른 사람들이 작성한 코드를 읽어보았다.

코드를 비교해본 결과, 해답 코드와 내 코드간 차이는 한 부분이었다.

조건을 ON에 걸었느냐, WHERE에 걸었느냐의 차이였다. 단편적으로 바라보았을 땐, 동일한 결과가 나올 것이라고 생각했지만, 사실은 달랐다.

 

상품의 가격은 판매기간에 따라서 변동사항이 생기고, 해당 판매기간 동안 판매된 상품의 수량을 파악해 판매된 금액의 평균을 ID별로 구분지어야하는 문제이다. 

테스트코드중에 가격은 명시되어있지만, 판매되지 않은 상품은 상품ID와 0으로 결과가 나와야한다. 

하지만 내가 작성한 코드로는 이미 필터링이 되어 원하는 칼럼이 결과로 나오지 않았다.

SELECT P.product_id, IFNULL(ROUND(SUM(UNITS*PRICE)/SUM(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;
------------------------------------------------------------
SELECT P.product_id, IFNULL(ROUND(SUM(UNITS*PRICE)/SUM(UNITS),2),0) AS average_price
FROM PRICES P
LEFT JOIN UNITSSOLD U
ON P.product_id = U.product_id 
WHERE U.purchase_date BETWEEN p.START_DATE AND p.END_DATE  # !! 내가 작성한 코드
GROUP BY P.PRODUCT_ID;

 

OUTTER JOIN 과정에서 ON과 WHERE 간 조건을 걸 때, 코드 실행 과정이 궁금해져 비교해보고자 글을 작성하게 되었다.


 

결론부터 말하면 ON은 JOIN이 실행되기 전에 먼저 필터링이 진행되고, WHERE은 JOIN이 실행된 이후에 필터링이 진행된다. OUTER JOIN을 활용하는 상황이나, 하나의 테이블을 기준으로 모든 PK를 결과로 나오게 해야하는 과정에서 주의해야할 것 같다.

 

- ON : JOIN 실행 전에 t2.몸무게=50 조건이 함께 필터링 되기 때문에 이름 A만 테이블이 연결되고 나머지 레코드는 null로 들어가게 된다. 사실상 1번,3번이 LEFT JOIN된거라고 봐도 무방하다.

- WHERE : JOIN 실행 후 t2.몸무게=50 조건이 필터링 되고, 모든 이름이 표시되어야하지만! 이름a 레코드만 결과로 나오게 된다. 여기가 내가 문제를 풀면서 놓쳤던 부분이다. 

물건이 아직 판매되지 않아도, 결과로는 이 물건의 id과 가격이 0으로 나와야하지만, 아무리 LEFT JOIN을 진행한들 필요한 레코드들이 전부 나오지 않았다. 

 

OUTER JOIN을 활용할 때는 ON과 WHERE의 실행순서를 잘 파악하고, 조건을 걸어야할 것 같다.


https://leetcode.com/problems/average-selling-price/

 

LeetCode - The World's Leading Online Programming Learning Platform

Level up your coding skills and quickly land a job. This is the best place to expand your knowledge and get prepared for your next interview.

leetcode.com

https://steadiness-193.tistory.com/248

 

SQL - JOIN 할 때 ON과 WHERE의 차이

[공통점] 둘 다 JOIN을 위한 조건절로 쓰인다. [차이점] ON - JOIN이 실행되기 전 WHERE - JOIN이 실행된 후 * 모든 JOIN은 LEFT JOIN으로 통일함 예시1. ON JOIN에 우선 이름으로 테이블을 연결한 뒤 AND t2.몸무

steadiness-193.tistory.com

 

반응형