CS/데이터베이스
Outer Join 주의사항
Junuuu
2023. 12. 6. 00:01
728x90
개요
bigQuery를 활용하여 두 테이블을 join 하다가 내 예상과 다른 결과가 나와서 당황했는데 근본적인 원인을 찾아 해결한 내용을 적어보고자 합니다.
시도했던 쿼리
-- 예상한대로 결과가 나오지 않는 쿼리
select *
from `myTable1` as C
LEFT OUTER JOIN `myTable2`as B on C.user_id = B.user_id
WHERE C.partition_dates = '2023-11-20'
AND C.탈퇴가_되지_않았으면_None인_필드 = 'None'
AND B.user_id is null
AND B.partition_dates = '2023-11-20';
B테이블과 C테이블을 비교하여 데이터 정합성을 맞추는 과정을 수행하고 있었습니다.
이때 LEFT OUTER JOIN을 수행하였으니 없는 필드는 null으로 조회될 것이라고 기대하였고 쿼리를 수행하였습니다.
또한 bigQuery에서 파티션날짜를 포함하지 않으면 데이터가 엄청나게 많아져 컴파일에러가 발생하는 상황이어서 파티션날짜는 필수로 들어가야 했습니다.
자연스럽게 없는 필드는 null으로 조회될것이지만 사실 밑의 쿼리 두 조건은 양립할 수 없는 조건입니다.
left outer join의 결과는 right 테이블에 userId로 조회되지 않아 null이거나 조회가 돼서 null이 아니거나입니다.
만약 B.user_id is null 조건문을 제거한다고 하면 어떻게 될까요?
조회가 돼서 null이 아닌 조건들만 조회될 것이고 자연스럽게 left outer join이 아니라 inner join과 동일한 효과를 내게 됩니다.
Subquery를 활용하여 개선
--- 예상한대로 동작하는 쿼리
select *
from `myTable1` as C
LEFT OUTER JOIN
(
select user_id
from`myTable2`
WHERE partition_dates = '2023-11-20'
)
as B on C.user_id = B.user_id
WHERE C.partition_dates = '2023-11-20'
AND C.탈퇴가_되지_않았으면_None인_필드 = 'None'
AND B.user_id is null;
subQuery를 통하여 내부에서 조건문을 수행해 주면 예상한 대로 결과가 잘 나옵니다.
참고자료