0Pricing
Coding Interview Prep · 강의

외부 JOIN에서 WHERE를 사용하는 함정

외부 JOIN된 열을 WHERE에서 필터링하면 외부 JOIN이 조용히 INNER JOIN으로 바뀌는 이유를 알아봅니다.

외부 JOIN에서 WHERE를 사용하는 함정은(는) CoddyKit의 무료 Coding Interview Prep 강의입니다. 이것은 4개 중 4번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 Coding Interview Prep 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. Coding Interview Prep 강의에는 총 4개의 강의가 포함되어 있습니다.

모두가 빠지는 함정

면접관이 준비하는 가장 흔한 외부 조인 버그입니다. “2024년에 주문한 내역과 모든 고객을 표시하되, 2024년에 주문하지 않은 고객도 포함하십시오.”라는 문제입니다.

지원자는 LEFT JOIN을 작성한 다음 WHERE에 날짜 조건을 추가하는 경우가 많습니다. 그러면 2024년에 주문하지 않은 고객이 조용히 사라집니다. LEFT JOIN이 조용히 INNER JOIN으로 약화됩니다. 그 이유를 이해하는 것은 숙련자 수준의 신호입니다.

잘못된 쿼리

다음이 실수한 예입니다. 모든 고객을 유지하고 고객의 주문을 조인한 뒤 2024년으로 걸러내므로 합리적으로 보입니다.

하지만 주문이 전혀 없거나 2024년에 주문하지 않은 고객은 결과에서 사라집니다. 이들을 포함해야 한다는 요구 사항을 충족하지 못합니다.

-- BUG: drops customers with no 2024 order
SELECT c.name, o.id, o.order_date
FROM customers c
LEFT JOIN orders o ON o.customer_id = c.id
WHERE o.order_date >= '2024-01-01';

작동하지 않는 이유

연산 순서를 떠올려 보십시오. 먼저 JOIN이 실행되어 일치하지 않는 고객의 모든 주문 열에 NULL이 들어간 행을 만듭니다. 그다음 WHERE가 실행됩니다.

일치하지 않는 고객의 경우 o.order_date는 NULL이므로 o.order_date >= '2024-01-01'은 참이 아니라 UNKNOWN으로 평가됩니다. WHERE는 참인 행만 유지하므로 NULL 행이 제거됩니다. 이는 LEFT JOIN이 보존하려고 했던 바로 그 행입니다.

NULL이 조건을 무력화하는 이유

NULL과 비교하면 어떤 비교 결과든 UNKNOWN이 됩니다. NULL >= '2024-01-01'은 UNKNOWN이고, NULL = 5도 UNKNOWN이며, 심지어 NULL <> 5도 UNKNOWN입니다.

WHERE는 TRUE로 평가되는 행만 통과시키므로, 보존된 일치하지 않는 행은 모두 제거됩니다. 오른쪽 테이블 열에 단 하나의 WHERE 조건을 적용하는 것만으로 외부 조인의 존재 이유가 사라집니다.

해결 방법: ON에 조건 넣기

조건을 ON 절로 옮기십시오. 그러면 조건이 일치 조건의 일부가 되어 행을 보존하기 전에 적용되므로, 일치하지 않는 고객도 NULL 값과 함께 계속 남습니다.

-- CORRECT: filter lives in ON
SELECT c.name, o.id, o.order_date
FROM customers c
LEFT JOIN orders o
  ON o.customer_id = c.id
  AND o.order_date >= '2024-01-01';
-- customers with no 2024 order: kept, NULL order

한 문장으로 보는 ON과 WHERE

면접에서 다음 규칙을 말할 수 있어야 합니다.

보존되는(외부) 테이블의 경우 다른 테이블에 대한 조건은 ON에, 보존되는 테이블 자체에 대한 조건은 WHERE에 둡니다.

  • ON은 무엇을 일치하는 것으로 볼지 결정합니다(조인 중에 실행됩니다).
  • WHERE는 최종 행을 필터링합니다(조인 후에 실행되며 NULL 행을 제거합니다).

나란히 비교한 결과

같은 데이터라도 조건을 어디에 두느냐에 따라 결과가 달라집니다. 캐럴에게 2024년 주문이 없다고 가정하십시오.

  • WHERE에 조건을 둔 경우: 캐럴이 사라집니다. 사실상 내부 조인입니다.
  • ON에 조건을 둔 경우: 캐럴이 주문 열에 NULL이 있는 상태로 한 번 나타나므로 요구 사항을 충족합니다.

이 결과 차이가 바로 이 함정의 핵심입니다.

-- ON version output
-- Alice | 50 | 2024-03-01
-- Bob   | 20 | 2024-05-02
-- Carol | NULL | NULL   <-- preserved

WHERE가 실제로 올바른 경우

외부 조인에서 WHERE를 사용한다고 해서 모두 버그는 아닙니다. 보존되는 테이블을 필터링하는 것은 괜찮습니다. 조인으로 생긴 NULL과 관련이 없기 때문입니다.

그리고 이전 수업의 안티 조인은 바로 이 동작을 의도적으로 활용해 WHERE o.id IS NULL을 사용합니다. 중요한 것은 지금 어떤 경우에 해당하는지 아는 것입니다.

-- Fine: filtering the preserved (left) table
SELECT c.name, o.id
FROM customers c
LEFT JOIN orders o ON o.customer_id = c.id
WHERE c.country = 'US';

탐지 방법

외부 조인을 검토할 때는 WHERE 절에서 보존되지 않는 테이블의 조건식을 살펴보십시오(IS NULL 안티 조인 확인은 제외합니다).

o.someColumn = ... 또는 WHERE의 외부 조인 쪽 범위/동등성 조건이 보이면 이 함정을 의심하십시오. “이 조건이 LEFT JOIN을 INNER JOIN으로 바꾸는가?”라고 물어보십시오. 대개 그렇습니다.

여러 조건

두 위치를 함께 사용할 수 있습니다. 오른쪽 테이블에 대한 일치 조건은 ON에, 왼쪽 테이블에 대한 실제 조인 후 필터는 WHERE에 둡니다. 두 조건은 문제없이 함께 사용할 수 있습니다.

SELECT c.name, o.id, o.amount
FROM customers c
LEFT JOIN orders o
  ON o.customer_id = c.id
  AND o.amount > 100          -- match condition
WHERE c.signup_year = 2023;    -- preserved-table filter

소리 내어 설명하기

면접에서는 해결 방법만 말하지 말고 작동 원리를 설명하십시오.

“조인이 먼저 실행되고 일치하지 않는 오른쪽 열에는 NULL이 채워집니다. 해당 열에 대한 WHERE 조건식은 NULL 행에서 UNKNOWN으로 평가되고, WHERE는 참이 아닌 행을 제거하므로 외부 조인이 내부 조인으로 축소됩니다. 조건식을 ON에 넣으면 일치 조건으로 남아 일치하지 않는 행이 보존됩니다.” 이 설명은 언제나 효과적입니다.

빠른 확인

모든 고객과 각 고객의 2024년 주문만 나열하되, 주문이 하나도 없었던 고객도 유지해야 합니다.

요약

보존되지 않는 테이블의 열을 WHERE에서 필터링하면 외부 조인이 조용히 내부 조인으로 바뀝니다. 일치하지 않는 행에서 나온 NULL 값은 조건식 평가를 UNKNOWN으로 만들고 WHERE가 이를 제거하기 때문입니다.

  • 외부 테이블에 대한 일치 조건은 ON에 둡니다.
  • 보존되는 테이블에 대한 필터는 WHERE에 둡니다.
  • WHERE의 IS NULL은 의도적인 안티 조인이며 함정이 아닙니다.
  • 연산 순서를 설명하여 제대로 이해하고 있음을 보여 주십시오.

자주 묻는 질문

“외부 JOIN에서 WHERE를 사용하는 함정” 강의는 무료인가요?

네 — “외부 JOIN에서 WHERE를 사용하는 함정” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 Coding Interview Prep 강의 전체를 잠금 해제할 수 있습니다. Coding Interview Prep 강의에는 총 4개의 강의가 포함되어 있습니다.

“외부 JOIN에서 WHERE를 사용하는 함정”에서 뭘 배우나요?

외부 JOIN된 열을 WHERE에서 필터링하면 외부 JOIN이 조용히 INNER JOIN으로 바뀌는 이유를 알아봅니다. 브라우저에서 직접 실행하는 실습 코드로 Coding Interview Prep을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.

Coding Interview Prep을(를) 시작하는 데 경험이 필요한가요?

사전 경험은 필요하지 않습니다. CoddyKit의 Coding Interview Prep은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 4번째 강의입니다.

“외부 JOIN에서 WHERE를 사용하는 함정” 강의는 얼마나 걸리나요?

대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.

이 Coding Interview Prep 강의에서 코드를 작성하고 실행할 수 있나요?

네. 모든 Coding Interview Prep 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.

이 강의의 모든 강의

  1. LEFT JOIN과 일치하지 않는 행 보존하기
  2. RIGHT 및 FULL OUTER JOIN의 의미
  3. 일치하는 값이 없는 행 찾기(안티 조인)
  4. 외부 JOIN에서 WHERE를 사용하는 함정
← Coding Interview Prep(으)로 돌아가기